SOA Manifesto – Now in 9 Languages!

I initially blogged about the SOA Manifesto that I was honored to be a part of almost a year ago. If you read through the signatories page, you’ll see some very prominent names (individuals and companies) and great comments supporting the work we did. We labored long and hard about the exact wording in English. The French looks good to me, but I’ll have to defer to others for the other languages.

Dutch is “coming soon”, but currently it is available at the site in:

  • English
  • Chinese
  • French
  • German
  • Italian
  • Portuguese
  • Russian
  • Spanish
  • Tamil

The languages may vary, but the value statements and principles are universal!

Solving the “No logical space left to create more user strings” Error and Improving performance of Pre-generated Views in Visual Studio .NET4 Entity Framework

As shown in the previous precompiled view blog (Isolating Performance with Precompiled/Pre-generated Views in the Entity Framework 4), views can significantly improve performance in various scenarios such as first-run; memory usage; and execution of one-off queries. However, the creation of views for large complex models that consist of many entities and associations), can create lots of views which in turn will require heavy use of strings, and reach the .NET metadata format limit on the number of user string characters (0xFFFFFF). Hence when trying to compile a project leveraging this type of views, the following compile error will occurred.

Error    1          Unexpected error writing metadata to file ‘D:\Compile view fix\…\PerfSample.exe’ — ‘No logical space left to create more user strings.’

For this reason, the following revisits this implementation and does two things, demonstrates how to further increase pre-compiled view performance and, at the same time, avoids the error on large complex models.

For ease of reading, it is recommended to review the previous post on pre-generated views.

Analysis

Looking at the generated code inside the pre-compiled view file, which by convention is named [projectName].views.cs; as seen below, one notices that in essence the code takes a number (an index) and with it searches thorough a large set of conditional statements to return the correct key value pair in a method.

Each method then returns the key value pair which consists of a set of strings, one for the key and another for the value, as seen here.

Design Approach

Here is where the number of user strings characters can reach the compiled limits. This is what needs to be avoided. For such, a couple of improvements will help.

First, instead of using plain strings, the code can reference a separate resource file and that way it will avoid reaching the compile limits on user strings.

Second, instead of IF statements, a dictionary that will return the required key value pairs will also improve efficiency.

To achieve this, a standalone application is needed. It will take the original view file and based on it, create a new pre-compiled view file that will reference a newly created resource file, as follows.

 

The code for this helper application can be downloaded from here; it is a console application that will take as the only parameter the EF pre-generated view file. Once it is done, it will create the two following files. Notices the simplification of the method returning the key value pair and how the resource file stores the strings as a key value pair in its raw .NET binary form.

WihtDictionary_PerfSample.views.cs

   

WihtDictionary.views.cs.resources

 

To use these files, first one needs to have a working EF solution which already implements a pre-generated view. Then, after running the above tool, the new dictionary pre-generated view file needs to be moved and renamed to replace the original EF created view file, and the resource file will need to be placed beside your executable file (in the case of a visual studio solution, it will be in the release or debug directory)

NOTE: as experienced, each time an EF generated pre-compiled view is replaced with a Dictionary pre-compiled view, the Visual Studio solution needs to be clear (From the tool bar: Build and then Clean Solution) before it is rebuilt.

The implementation

At run time, the new view file which implements a generic IDictionary, will get populated at the point where the class is instantiated (its constructor) by using the key value strings found in the new resource file. See below.

The new generated view file is fairly similar to the original file: namespace, class name, method names, as well as the hard coded hash values which EF uses as reference to check that the view strings have not been modified. This last point means that the strings being stored in the resource file will need to be exactly the same as those extracted from the original generated view file (no extra or missing spaces or newlines nor commas…).

Everything else will remain exactly the same: the CSDL, MSDL and SSDL as well as the ObjectLayer and App.config files will not require any changes since the fact that a dictionary and a resource file will be used instead of the conditional statements should be completely transparent to all other “moving parts”.

Testing the theory

So far this seems fairly believable but what gain should be expected? This will of course vary on the characteristics of the model and the underlying database but by leveraging the methods described in the blog on Isolating Performance with Precompiled/Pre-generated Views in the Entity Framework 4, and gathering results for both the original views and the dictionary views, the following results can be observed.

NOTE: For large models, the use of T4 templates for view generation may be very slow and may crash Visual Studio; therefore the use of EDMGEN will be more appropriate.

(*) Total entities

With original pre-compiled views

With dictionary pre-compiled views

100

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      2,094  | 63,224,212  |

|        564  | 54,347,924  |

|        651  | 54,352,824  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      1,993  | 64,264,668  |

|        677  | 53,303,412  |

|        658  | 54,348,216  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      1,976  | 63,224,084  |

|        594  | 54,347,796  |

|        600  | 54,353,592  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      1,998  | 61,385,776  |

|        579  | 53,299,864  |

|        605  | 53,303,996  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      2,076  | 61,384,496  |

|        684  | 53,299,864  |

|        571  | 53,299,388  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      1,911  | 61,383,728  |

|        628  | 53,299,992  |

|        616  | 53,299,516  |

300

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      4,631  | 81,378,508  |

|        645  | 53,299,956  |

|        803  | 53,304,344  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      4,585  | 81,377,100  |

|        694  | 53,299,956  |

|        777  | 53,304,344  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      4,426  | 81,373,388  |

|        854  | 53,304,052  |

|        658  | 53,300,248  |    

 ...\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      4,401  | 75,376,604  |

|        755  | 53,304,052  |

|        797  | 53,300,248  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      3,984  | 76,426,788  |

|        804  | 54,351,544  |

|        762  | 53,300,248  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      4,114  | 76,428,708  |

|        783  | 54,347,960  |

|        742  | 53,304,344  |

500

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      6,933  |101,150,740  |

|        578  | 55,274,548  |

|        551  | 55,266,648  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      6,678  |101,145,472  |

|        606  | 55,274,548  |

|        534  | 55,266,648  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      7,054  |101,150,724  |

|        642  | 55,274,420  |

|        566  | 55,266,648  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      6,168  | 90,127,776  |

|        651  | 55,270,416  |

|        579  | 55,270,708  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      6,411  | 90,127,776  |

|        554  | 55,270,416  |

|        761  | 55,270,708  |

…\bin\Release>call PerfSample 

| Time MilSec |Manage Bytes |

|—————————|

|      6,327  | 90,127,776  |

|        717  | 55,270,416  |

|        732  | 55,270,708  |

700

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     14,051  |117,458,568  |

|        828  | 55,267,344  |

|        770  | 55,267,636  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     12,254  |119,724,760  |

|        786  | 55,271,476  |

|        805  | 55,271,768  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     12,795  |119,721,560  |

|        888  | 55,271,476  |

|        785  | 55,271,768  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     10,576  |104,291,448  |

|        656  | 55,271,348  |

|        764  | 55,271,640  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|      9,875  |104,291,960  |

|        766  | 55,271,476  |

|        771  | 55,271,768  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     10,103  |104,295,160  |

|        731  | 55,271,348  |

|        795  | 55,271,640  |

1000

 

 

 

 

 

 

 

Not applicable, build error:

 

‘No logical space left to create more user strings.’

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     14,708  |124,840,944  |

|        539  | 55,273,140  |

|        543  | 55,273,432  | 

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     11,214  |124,841,584  |

|        633  | 55,273,140  |

|        657  | 55,273,432  |

…\bin\Release>call PerfSample

| Time MilSec |Manage Bytes |

|—————————|

|     11,239  |124,841,584  |

|        594  | 55,273,140  |

|        627  | 55,273,432  |

(*) Note that this is only a reference number, the model been created are very simple and therefore should only be used as reference and not as a close approximation of what a real-life model maybe. Running similar tests against the implemented models is recommended.

This isolated tests show that the improvements are more apparent with larger models. For the 1st run the gains in time are modest, 100 and 300 entities are about 1% ~ 3% faster, the memory usage is between 3% ~ 5% less too. At 500 entities the 1st time runs gains are noticeable, in both time and memory, at around 8% ~ 10%, and subsequent runs are very uneven likely due to other types of cache (server RAM, SQL cache…) taking effect. The real gains are seen at 700 entities, where the 1st runs were 25%, 20% and 37% faster in time to completion and memory usage drops by about 12%, and time lapse on subsequent runs are now a more even, where dictionary pre-compiled views are around 7% faster. The true difference is obviously at 1000 entities, since this method becomes the only way views can be utilized.

Conclusion

The use of a dictionary is creating a first time cache like behavior and hence the 1st load runs are considerably faster (over 25% in cases with large amount of models), in subsequent runs other types of cache (server RAM, SQL cache,…) take precedence but gains of 7% can be seen in large models. The method of using a resource file helps with memory management while processing the same amount of large strings and as such, the usage of managed memory drops on all tests.

The larger your model, the more reason to implement this method, as all the analyzed data points show improvement. In the cases where the compiled error is discovered, then this becomes the only method to work around the issue. As always, first do in-house tests before full production implementation.

 

Recent Launch of AppFabric CAT blog…

Hi folks, an email floated across my desk from Tim Wieman today tell me about a new AppFabric CAT blog.

Thanks Tim.
— snippet —

Recently as part of building the Windows Server AppFabric Customer Advisory Team (or AppFabric
CA
T for short).  This team brings under one “virtual roof” others like me
from the team formerly known as the “BizTalk Rangers”, plus other technology experts
in Windows Server AppFabric, AppFabric Caching, WF, WCF, StreamInsight, EF, etc.

The
new team blog is our commitment to deliver technical guidance and share best practices
with the rest of the world-wide community.  We are also working on the
AppFabric CAT
portal, a brand-new web site that will serve the purpose of the “one-stop shop” for
all the great deliverables that our team will be producing for the community going
forward (similar to sqlcat.com).
 
Please
check out our team blog at http://blogs.msdn.com/appfabriccat.


P %u2260 NP proved?

Oh my.Somehow I missed this one from earlier this month. A guy from HP Labs called Vinay Deolalikar claims he has the proof.P %u2260 NP.I’m nowhere near clever enough to follow his arguments (see http://www.hpl.hp.com/personal/Vinay_Deolalikar/Papers/pnp_synopsis.pdf for a synopsis), but I understand the impact.
If he is right, then in a sense, nothing changes.It’s just that we will now know for sure that there is no magic formula that will revolutionise the efficiency of our software. The proof will confirm what has been long suspected.However, if the proof holds up, then it is a major milestone in computer science.I mean MAJOR.
Nothing personal against Mr Deolalikar, but I really hope the proof does not hold up.The idea that P could just possibly equal NP is so beguiling.
No idea what I am talking about?Here comes Wikipedia to the rescue! http://en.wikipedia.org/wiki/P_%3D_NP_problem
And here is a really easily digestible explanation from the good ol’ BBC.Jigsaws work for me!

Microsoft’s Windows Server AppFabric Customer Advisory Team ( CAT)

Microsoft’s Windows Server AppFabric Customer Advisory Team ( CAT) has launched a new blog focused on AppFabric (both Windows Server AppFabric and Azure AppFabric), WCF, WF, BizTalk, data modeling and StreamInsight. This team contains the artists-formerly-known-as-BizTalk-Rangers, and they provide deep expertise on BizTalk Server, Windows Server AppFabric, WCF, WF, AppFabric Caching and StreamInsight (CEP). These technologies become more and more important in time to come, when it comes to integration, process automation, SOA and Cloud Computing. This is something to look at closely and I suggest to digest it’s content. Also I suggest to read Richard’s post on Microsoft Customer Advisory Teams, and why should know them.

Technorati: biztalk server 2010 appfabric

IE9 Chrome

It was always obvious that IE9 was going to get new chrome. Why else publish the technical previews with a mocked-up UI? The very fact that the IE team has cleanly separated the core browser technology from the oldIE chrome indicates that they are free to change the whole look and feel of the browser if they wish. And of course, they must want to do so. Everyone loves the clean, zippy feel of Google’s Chrome. If IE9 is to halt the slow slidein ‘market share’that previous versions of the browser have experienced in recent years, it is Google they must take on, more so than any other browser. Yes, Firefox holds second place, but its growth hasstagnated. Google Chrome, on the other hand, is on a steady and solidtrajectory upwards.

After years of effort having to chase the alternatives and constantly being behind the curve, IE9 represents a real change in the fortunes of what is still the world’smost widely used browser. Microsoft return to where they could always have been if they hadn’t decided all those years ago to abandon further development of IE, loosing years of advantage in the process. IE9 has already forced Google and Firefox to speed up implementation ofGPU support (it would be unthinkable for them not to have responded to the amazing graphic performance of Microsoft’s preview). It is in grave danger of coming out top in just about every official standards compliance test. It’s new Javascript engine is right up there, performance wise, with Google Chrome, Safari and Opera, and way ahead of Firefox. It will even shortly achieve 100/100 on Acid 3 (almost there now). And now we get our first glimpse of the new Chrome-like chrome. It’s the dawn of a new age for the old browser and I can’t wait to get my hands on the beta.

http://www.zdnet.com/blog/microsoft/is-this-microsofts-new-internet-explorer-9-interface/7213?tag=mantle_skin;content

BizTalk Performance session at Tech·Ed Europe 2010

I just got the news my BizTalk Performance Optimization session was approved for Tech%u00b7Ed:

Topic Information

Primary Track
Application Server & Infrastructure

Session Type
Lunchtime Session

Session Title
BizTalk Server Performance: Configuring BizTalk Server for performance

Description
Optimizing and verifying your BizTalk Server installation is not an easy thing to do. The documentation is good but very extensive. This presentation aims to guide you through the most important operations you need to do in order to boost the performance of BizTalk. The session includes a live demo where these settings are applied and how it significantly improves the performance.

Major Products or Technologies Covered
Microsoft BizTalk Server 2010, Microsoft SQL Server 2008 R2

 

Hope to see you there. Let me know you’re coming.

Converting a C# workflow into XAML

A interesting question that came up last week was how to convert workflows defined in C# to XAML.

A co worker of one of the attendees of the Essential Windows Workflow Foundation 4 course had been experiencing a lot of problems with the workflow designer and decided to create their workflows in C# instead of using the designer to generate XAML. While these workflows run just fine you do lose the visual aspect of the designer, one of the benefits of workflow in the first place.

Fortunately it isn’t hard to save workflow objects, however they have been authored, into their XAML representation using the XamlServices.

Take the following workflow defined in C#.

var workflow = new Sequence();
workflow.Activities.Add(new WriteLine() { Text = "Hello workflow." });
workflow.Activities.Add(new Persist());
workflow.Activities.Add(new If()
{
    Condition = new VisualBasicValue<bool>("System.DateTime.Now.Hour < 12"),
    Then = new WriteLine() { Text = "Good morning" },
    Else = new WriteLine() { Text = "Good afternoon" }
});
workflow.Activities.Add(new WriteLine()
{
    Text = new VisualBasicValue<string>("\"The current time is: \" & System.DateTime.Now.ToLongTimeString()")
});

This will run just fine as is but if I want to convert this into XAML all I need is a single line of code:

XamlServices.Save(@"..\..\demo.xaml", workflow);

And when it runs I get a nice XAML file with the graphical representation of the original C# workflow.

And now I can continue enhancing the XAML version and run that instead.

 

Enjoy!

www.TheProblemSolver.nl

Wiki.WindowsWorkflowFoundation.eu