Wednesday, September 24, 2008

Day of .NET -- Ann Arbor



I got word this morning that I will be speaking at the Ann Arbor Day of .NET.

I am excited about this since it is my first conference. I have given public seminars, and recently gave a talk at the Ann Arbor .NET Users' Group, but this is my first conference.

My talk will be about testing WinForms apps using NUnit. I have been developing my technique for testing WinForms GUIs for over a year now and I have learned a lot about the topic. It should be fun!

This conference is free, so get registered soon!

Monday, September 22, 2008

Why you REALLY need to think about your interfaces

kick it on DotNetKicks.com

I was working on performance tuning an application the other day.  The code in this post is a rough approximation of the problem I had to solve.  The application defines a plug-in interface that the plug-in developers can implement.  The plug-in gets initialized with a dictionary and and the application talks through the rest of the interface.

public interface IPlugin   
{
void Initialize(Dictionary<string, Information> dataLibrary);
string TalkToMe(string message);
}

The initialization from the application is simple:

public void SetUpPlugin(IPlugin plugin)   
{
Dictionary<string, Information> data = PopulateDictionary();
plugin.Initialize(data);
}

When this interface was originally written, the dictionary was populated using XML files.  The dictionary only included about two hundred items, but over time, this dictionary became more complex.  It grew out of the XML files, and into a database.  It grew into tens of thousands of items.  It is not hard to tell that there is a performance bottleneck here as the application populates this many items from the database.  It turns out that the plug-ins don't tend to need a lot of the data in the dictionary, though I cannot predict what it will need to lookup.  To populate the entire dictionary takes a TON of time, and it is completely unnecessary.

Unfortunately, I am bound to this interface, which is already published to our plug-in developers.  My first inclination was to write a custom Dictionary<> class.  It would be really nice if .NET would let me do something like this:

public class DataLibrary : Dictionary<string, Information>   
{
private IApplicationLogic _logic;
public DataLibrary(IApplicationLogic logic)
{
_logic = logic;
}

public override Information this[string key]
{
get
{
return _logic.LookupInformation(key);
}
}

public override int Count
{
get
{
return _logic.InformationCount;
}
}

// etc
}

This would solve my needs completely if only methods were not sealed by default in C#.  Unfortunately, they are, and .NET didn't make the Dictionary members virtual.  In fact, it turns out, I am completely coded into a corner since I can't change the interface.  If only the IPlugin interface were thought through a bit further, I wouldn't be in this predicament. 

All that really needed to happen was for IPlugin.Initialize to take an IDictionary<string, Information> instead of a Dictionary<string, Information> (notice the 'I' in front of the Dictionary, indicating that it is an interface as opposed to a concrete class.)  If this were only the case, I would be able to implement the interface using a database lookup and move on with my life.

Now, I really don't have any solution other than asking for an interface change to all of the plug-in writers for my application.  This not only looks bad, but it IS bad.  I suppose might be able to come up with something crazy using Dynamic Proxies, but that would get rather ugly rather quickly.

The more you think about it, the choice of Dictionary<string, Information> was bad for other reasons as well.  The Dictionary class is a read/write class.  We do not want our plug-in authors to modify the dictionary -- we only want them to look up data.  We don't need them to iterate over the data, and we don't need to give them a vectored view of the keys or the values.

The message I am trying to get through here is simple:  When you are creating an interface for public use, you need to think hard about what that interface looks like.  Avoid concrete data passing when interfaces are available (IDictionary instead of Dictionary).  These interfaces don't get to change much.  They aren't as flexible as the internal code.  Please, think about your interfaces.

Friday, September 12, 2008

Have you seen the new ANTS profiler?



kick it on DotNetKicks.com
Before I write anything, I want to make it clear: I am not a Red-Gate shill. They have not paid me to say this... in fact, my team pays them for their software. I just feel that sometimes, you just need to recognize superior work.

Edit: Since writing this post, Red-Gate has sent me a SWAG package with a T-Shirt, coffee mug and 1 GB USB drive. They did this to thank me for the testimonial of mine that they published. Again, this happened AFTER this post, and I am still not a Red-Gate shill.

ANTS of the Past
My team has been using the .Net ANTS Profiler for years. It has always been a useful tool in our arsenal for finding performance bottlenecks. In the past, I have always liked the product, but have never felt like it was anything extremely special. One of the biggest reasons for this is the often mis-represented hot spots.

I often found that methods that got called many times (hundreds of thousands) would show up as hot spots in ANTS. When I worked to reduce the number of calls, my app would fail to show improvement. ANTS would show me the next hot spot and I would be fooled again.

The reason for this (as I theorized) was that ANTS was measuring the profile time in addition to the method time. The profile time outweighed the execution time, thus erroneously pointed out a hot spot. Admittedly, reducing the call count was good for my software but it wasn't my primary goal for profiling. Eventually, I would find the real bottleneck and fix it. Ultimately, the tool did a lot of good for our software.

The New ANTS 4.0
When version 4.0 of ANTS came out, I was very interested to see what they had to offer. I was pleasantly surprised with what I found. The ANTS team completely re-wrote their profiling engine AND the UI. Both of these re-writes have been a home run thus far.

Accuracy
The most important improvement is the accuracy of the results. I have used the new product to find several hot spots. This time around, it is extremely accurate. For instance, when I profiled a particular action, ANTS found a hot spot that was taking 27% of the time. When I implemented caching for that particular code and timed the action again, I got a 26% improvement from my fix. This is the type of accuracy I have been waiting for. I have had several other successful finds like that.

One other notable feature: recognition of the JIT compile time. In one particular action with a rather deep call stack, ANTS was able to tell me that 38% of my time was spent in the JIT compilation. It was useful to know where the time was being spent.

The Timeline
OK, now to the UI improvements. ANTS 4.0 features an interactive time line of the execution. You have the ability to track any system counters, but it tracks the processor utilization by default. As it goes, it marks the important events such as button clicks and window events. At any given time, you can select any subset of the time to profile. You can even bookmark those subsets so you can look at it later. They even allow you to zoom in to the graph. In all, this is a GREAT feature.

Tree View
In the previous versions, the primary view of the data was a data grid. The data grid has not been removed in 4.0, but it is no longer the primary view. Instead, it is a tree view. This is great as it is a much more natural visualization of the data.


Graph View
As nice as the tree view is for finding problems, the graph view is best for communicating bottlenecks to others. You have control over which nodes in this graph are shown. Take a look:


Code View
Finally, the code view is similar to previous versions of ANTS. One notable new feature is the ability to navigate the code from this view. You can now click on the methods in the view and it will take you to that method. I have found myself using it a lot.


Conclusion
In all, this is more than a version upgrade. It is mostly a new tool. You can find several similarities with the old tool, but you will find more differences... in a good way. Kudos to the team that put this together. It has become one of my favorite tools in my development tool belt.

Thursday, September 11, 2008

Castle Active Record Slides and Links



Last night (9/10/08), I had the pleasure of speaking at the Ann Arbor .NET Developers Group. This was my first public talk in several years, and my first since switching my career focus from Linux to Windows. I had a great time, and I want to thank the group for giving me the opportunity to talk.

As promised, I am posting the slides from my talk (PDF). In addition, here are several links that I included in my talk: