Monday, April 28, 2008

Sorting Performance of Dynamic Linq

I have really just started scratching the surface of Linq & C# 3.5. One thing that I was instantly dissapointed was how the sorting is implemented. In my web application all of our grids are sortable and prior to Linq I wrote a little IComparer implementation which uses reflection to access any property we need.

The issue I have with the linq implementation is that if the columns we are sorting on can change, I would have to have different lambda expression for all the possible permutations. This is not acceptable.

The Dynamic Linq Library is included in the C# Linq Samples. I highly recommend looking into the dynamic library. It allows for the lambda expressions to be expressed using a very easy to learn syntax, which is stored as a string. This allows you at runtime to easily build dynamic expressions for example:


lines.AsQueryable().OrderBy(field + " " + direction.ToString());




How does this perform compared to the reflection based implementation? I have not done a full analysis and only have time for a quick look at it but from what I have it is not to bad. For the record I am running a 2.5GHZ Dual Core Intel with 3 GB of Ram running on Windows Vista. We will be sorting 100 classes in a List<> object. The classes have two integer properties which were randomly seeded.

As expected the first pass through the code is the most expensive but how expensive is it?

  • Dyanmic Linq: 15.5 MS
  • Reflection: 5.5 MS
  • Linq Query: .87 MS

This is expected since the Dyamic Linq is building the expression trees. If your only going to sort a list once then going with reflection here might be more appropiate due to the 300% overhead of the dyanmic query; however, what happens if you end up sorting the same collection 100 times. For this test, I decided to sort the same list each time only I would swap between two different integer properties.


  • Dynamic Linq: 26 MS
  • Reflection: 195 MS
  • Linq Query:1.87 MS


I was shocked by this. I had thought that by changing the dyanmic expression it would have to re-initalize itself. Looks like I was wrong. A normal linq query is definetly the fastest approach; however, I feel that due to its inflexibility, the dynamic approach is a better aproach.

Friday, April 25, 2008

Web Deployment Projects & Updateable Sites

I am growing very fond of the Web Deployment Project for Visual Studio. I have found it to be an integral piece of my web site; however, I have just ran into a small gotcha which is related to the Allow site to be updated option (Note: This option is not specific to the web deployment project but a part of the ASP.Net compilation model).

One of my web pages is a highly customized printout. I leveraged server side code in the .aspx page to simplify which elements are displayed take the following html fragment for example:



<%if (DisplayAllines)


{%>


<div style="float: right">


<asp:Table ID="lines" runat="server" />


</div>


<%}


else


{ %>


<div style="float: right">


Grand Total:


<%=Bid.GrandTotal().ToString("C") %>


</div>


<%} %>





When you publish your site as updateable, the server side code here is not compiled. I had accidently used the wrong capitlization for an abbreviation in simillar code, and while it compiled without a problem, it would not run.

If you turn off updateable site feature, and run a build, Visual Studio does catch the syntax error.

On a side note I wish Microsoft would better support server side scripting tags. I use these a lot in some of the javascript for my user controls (Particulary if the control will exist multiple times on the same page), as a way to quickly and easily distinguish btw javascript objects. For example:



var <%=this._gridAssets.ClientID %>GridSelection;


var isError=false;


function onLoad<%=this._gridAssets.ClientID %>Grid(sender,eventArgs)


{


    <%if(!ReadOnly){ %>


    <%=this._gridAssets.ClientID %>GridSelection=new selectedGrid(sender,4,null);


    <%} %>


}




In this example here, I have a custom javascript object which is associated with a grid in this user control. I use the ClientId of the grid to act as a namespace. This same trick is also handy if you need to access server side controls from javascript and those controls will exist in a naming container.

When you do this you will be flooded with syntax warnings as the parser is trying to treat the script directives as client side script. Intellisense almost never works here either (It will work outside of a <script> tag).

Enjoy!

Monday, April 14, 2008

Rebuilding Indexes in SQL2005

I have been developing on Microsoft's SQL Server since SQL 2000; however, I always had the luxury of having a dedicated IT team who was in charge of managing the production environments. Now that I am working for a startup company and am the sole developer, build engineer, and production team, I have to handle this aspect of my job.

I ran into what I will call a bug in SQL 2005 that I can't believe has made it into SP2. And while as you will see this bug is very minor it is a good example, of a poor design of a management tool and error handling.

I am setting a new nightly maintneance plan and set it up with the following steps:
  1. Check Database Integrity (Right now our DB's are so small that I am going to do this nightly but some people recommend weekly is sufficent)
  2. Rebuild Indexes
  3. Full Backup of Databases
  4. Cleanup Old Backups
  5. Notify Operator

I go ahead and run the backup, and I notice my databases are backuped to the location I specify, yet the UI tells me that the job has failed. I open up the job details and I see the following error message:

Date 4/14/2008 9:30:06 AMLog Job History (Nightly
Maintneance)
Step ID 1Server XXXXX
Job Name Nightly Maintneance
Step Name Subplan
Duration 00:01:27
Sql Severity 0Sql
Message ID 0Operator Emailed Operator Net
sent Operator Paged Retries
Attempted 0
MessageExecuted as user: XXXXXX
The package execution failed. The step failed.



All this is telling me is that a step failed. It provides no indication of what failed or why. I brough up the report from the maintneance package it told me to check the SQL Agent Job history to find out why it failed. Which as I showed is not helpful.

So I resorted to the only option I felt I had, I disabled every step and ran each one building upon each other. This is when I noticed the issue. I had setup the Rebuild Index task to "Keep index online while rebuilding" option selected.

Online indexing is a new feature in SQL 2005 that helps improve your uptime since you can do maintneance on your indexes without taking them offline. So I had though let's select this option.

This option doesn't work for my environment because we are using SQL Server Standard edition. Here's my gripe about the error handling here. Why didn't the error messages indicate that the rebuidling indexing failed? Better question is: Why is this package even allowed to be created?


Editors Note
Since writting this I have discovered that better error information is available in MSSQL\LOG directory. While this is useful, and in fact in this case it does say exactly the problem, I feel my post still holds true. The SQL Management Studio should have provided me better error information, or even better disabled that option entirely.