Tuesday, January 11, 2011

The collected works of others

This is an assortment of links to articles and posts that I found interesting at one point or another. I’ve collected these over the past couple of years in various places for various reasons.  Now they’re all in one place in no particular order so you’ll have to just read them all.  Enjoy.

“Anxiety is nothing but repeatedly re-experiencing failure in advance” – Seth Godin

Wednesday, January 5, 2011

Poor man’s Entity Framework profiler

We recently added the ability to trace the Sql statements being executed by an EF query.   This is a companion to the code that was added long ago to the Enterprise Library to do the same thing.  In the case of the Enterprise Library we customized the library itself to trace the Sql before being executed.  This has been useful numerous times for troubleshooting performance issues.  In those cases its been very handy be able to see all the Sql being executed, to know which queries are taking the longest and/or called the most in a given context. 

However, our move to EF had left gaps in this tracing, reducing our visibility into what was was being called and how often.  EF, because it generates its Sql, also reduced our visibility into the Sql itself.  While troubleshooting performance problems in our poor performing “Customer View” page we had need to add EF tracing in order to get the full performance picture.

In our case we are essentially only using two methods that cause EF queries to execute, ToList(), FirstOrDefault().  Therefore, I created two IQueryable extension methods, ExecuteToList(), ExecuteFirstOrDefault(), and replaced all calls to the former with the latter.  The two Execute* methods are simply wrappers that delegate to their counterparts.  The advantage being that within the wrapper methods we can inject tracing logic.

        public static TEntity ExecuteFirstOrDefault<TEntity>(this IQueryable<TEntity> query)
{
DebugQuery(query);
var executeFirstOrDefault = query.FirstOrDefault();
Debug.WriteLine("**********End************");
return executeFirstOrDefault;
}

public static List<TEntity> ExecuteToList<TEntity>(this IQueryable<TEntity> query)
{
DebugQuery(query);
var executeToList = query.ToList();
Debug.WriteLine("**********End************");
return executeToList;
}

private static void DebugQuery<TEntity>(IQueryable<TEntity> query)
{
#if DEBUG

Debug.WriteLine("**********Begin************");
var stackTrace = new StackTrace();
var method = stackTrace.GetFrame(2).GetMethod();
Debug.WriteLine(string.Format("{0}.{1}", method.DeclaringType.Name, method.Name));
Debug.WriteLine(query.ToTraceString());
#endif

}

The moral of this story is that if you want tracing you now have to make sure you’re using the extension methods rather than the base methods.

Monday, January 3, 2011

RIF Notes #1

"If it is fast and ugly, they will use it and curse you; if it is slow, they will not use it." -David Cheriton in _The Art of Computer Systems Performance Analysis

“The basic advice regarding response times has been about the same for thirty years [Miller 1968; Card et al. 1991]:
•0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
•1.0 second is about the limit for the user's flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
•10 seconds is about the limit for keeping the user's attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.
“ - Jakob Nielsen

“Whatsoever I've feared has come to life, And whatsoever I've fought off became my life”