Wednesday, September 19, 2007

.NET 3.5 Beta 2 - no LINQ performance improvements?


     Today I've got a comment on my post where I compared performance of LINQ vs. DAAB vs. ADO.NET, saying that I should repeat my test with .NET Framework 3.5 beta 2. Indeed there are a lot of posts about performance improvements introduced in it, so I've rushed and repeated my test, compiling it in Microsoft Visual Studio 2008 Beta 2, targeting .NET 3.5 beta 2.
     Not sure that proverb "no news - good news" is correct in this case, but - well - no news. I mean that performance results are absolutely the same - LINQ is about 30% slower than raw ADO.NET (4.28 ms per call for ADO.NET vs. 5.51 ms per call for LINQ). Also, using LINQ rather than ADO.NET makes application much more CPU intensive (something like ~20% of CPU intensity with LINQ vs. ~2% of CPU intensity with ADO.NET - difference of order of magnitude!). You may see screenshots below.

Timing results


CPU Intensity.(First third - ADO, second - DAAB, third - LINQ.)

So it seems to me that there are no significant performance improvements, unless there is something fundamentally wrong with my tests (check code here).

     Yet - I want to develop here something I've mentioned in my previous post. This additional performance cost doesn't mean "don't use LINQ". You'll probably never will get to performance incur of 30% in the real project. In the real life scenario you'll never abuse your DB by shooting thousands of SP calls in a batch, without doing something with results. There is always some business logic around, some DAL, some timings, etc - so the performance costs are never so high and they will be spread around evenly, rather than composed into a performance-loss peak. Also - mind that LINQ greatly improves coding productivity, decreases amount of code and project complexity. This means that developers would spend less timing coding and the costly thing for the project is the developer time. In the very worst case - profile your application to find the bottlenecks of 20:80 rule and use ADO.NET in critical sections of your code. And buy quicker CPU - they are cheap today :) ...

P.S.
     Few links to related articles:


Sunday, August 19, 2007

How to give alias to the SQL Linked Server


There are no problems to add SQL linked server to the specific host running it. But what if you need to give it an alias, rather than use hostname as linked server name?
Here is how to do it:
1) Step 1:
• In SQL Server Management Studio open Linked Servers and then 'New Linked Server'.
• Inside of appeared wizard – Select the General tab.
• Specify alias name in "Linked server" field.
• Select SQL Native Client as provider.
• Add sql_server in "Product Name" field (that's the magic).
• In "Data Source" – specify name of the host to be used as linked server.
2) Step 2:
• In Security tab – specify proper security options (e.g. security context)
3) Step 3:
• In Server Options tab – put "Data Access", RPC, "Rpc Out" and "Use Remote Collaboration" to be true.
4) Step 4:
• Enjoy.

How to create WCF service proxy without publishing mex endpoint


Some time ago I needed to create WCF service proxy, while I don't wanted to expose and publish MEX endpoint for it (and then generate the proxy from its wsdl). Strangely, but I didn't found any clue on how to do it in the Google depths. Even MSDN articles (1 and 2) devoted to the SvcUtil doesn't mention it in a straightforward way. Here is how to do it:

1) Create WSDL and XSD definitions for your service. Use following command:
svcutil /serviceName:MyService.MyServiceClass MyServiceAssembly.exe /reference:MyServiceContracts.dll
(You'll need to reference additional assemblies related to the service, like I did with MyServiceContracts.dll)

2) Generate proxies and corresponding client WCF configuration in .config file:
svcutil *.wsdl *.xsd /language:C#

Wednesday, August 15, 2007

In order to add an endpoint to the service MyService, a non-empty contract name must be specified.


Are you getting InvalidOperationException while creating ServiceHost for your service and getting message in style of "In order to add an endpoint to the service 'MyService', a non-empty contract name must be specified."? the probable reason is that you've missed contract definition in one of it's endpoints. Go to the endpoints list in your .config file and check that each endpoint has 'contract="MyContracts.IMyInterface"' tag.

DEV012 Building WPF XAML Browser Applications - few patches



Few patches you may need to use for this lab:
  1. You getting "Error 32 SignTool reported an error SignTool Error: Signtool requires CAPICOM version 2.1.0.1 or higher" - solutions is here.

  2. You getting "Request for the permission of type System.Net.WebPermission" - it could be caused by a range of reasons. In my case - I needed to set Execute permissions to "Scripts only" rather than "Scripts and Executables". If it not helps you - here few more receipts:

Thursday, August 09, 2007

Consolas - ClearType font optimized for programming environment

DEV012 Building WPF XAML Browser Applications - few patches

Few patches you may need to use for this lab:

  1. You getting "Error 32 SignTool reported an error SignTool Error: Signtool requires CAPICOM version 2.1.0.1 or higher" - solutions is here.

  2. You getting "Request for the permission of type System.Net.WebPermission" - it could be caused by a range of reasons. In my case - I needed to set Execute permissions to "Scripts only" rather than "Scripts and Executables". If it not helps you - here few more receipts:

Wednesday, August 08, 2007

WCF Performance

JSON Date deserialization fails at client
Some time ago I've developed a Comet infrastructure for the ASP.NET Ajax. As part of its possibilities - it enables to serialize server-side objects and stream them to the handling function at client side. It was working like a breeze, until Ive streamed some object with Date field, say something like that:        
public class TestMessage        
{            
public string _s1 = "s1";            
public int _i1 = 1;            
public DateTime _t1 = DateTime.Now;        
}


Now, an instance of this TestMessage was correctly deserialized into JS object, exclude its DateTime fields, which was appearing in following form:
{...}
_i1: 1
_s1: "s1"
_t1: "/Date(777)/"


If youre affected by similar problem here is the reason:
1) JSON representation for the string was changed from @777@ to \/777\/ in the latest Ajax release (to prevent serialization of strings that looks like date into Date format), where 777 is num of milliseconds since January 1, 1970 UTC.
2) Currently - at the server side DateTime object is serialized as "_t1":"\/Date(777)\/"
3) If you stream it as-is to the client-side JS recognizes single \ as escape character and your date actually became /Date(777)/, which is wrong format for deserialization.

So, if you want to stream your objects correctly you here is small RegEx-based utility Ive did for it:        

private static class ReplaceDateOrchestrationRegularExpression        
{            
private const string _regex =                
"(?\")(?\\\\)(?/Date\\([\\d]+\\))(?\\\\)(?<" + "postfix>/\")";            
private static readonly RegexOptions _options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase);            

public static readonly Regex Expression = new Regex(_regex, _options);            
public const string ReplaceOptions =                
@"${prefix}${firstDateSlash}\${body}${secondDateSlash}\${postfix}";        
}        


private static string ConvertToClientSideJson( string jsonedArgument )        
{            

return ReplaceDateOrchestrationRegularExpression.Expression.Replace(
jsonedArgument,
ReplaceDateOrchestrationRegularExpression.ReplaceOptions);        
}