Test INotifyPropertyChanged Pattern implementations

Today, I'll cover a well known topic: different implementations of the INotifyPropertyChanged interface (henceforth referred to as INPC). Its most common use is when you're implementing the MVVM pattern. This interface makes sure that your viewmodel properties update the binded interface components when you change the property value. So, with so many WPF and silverlight applications out there, it's a well known interface and you probably also know that it's regular implementation is somewhat boring and extensively verbose! That's why there are so many different alternatives out there. I decided to collect a few and test them for performance.
The main motivation was to validate the suspected performance penalty of implementations based on expression trees. So I'm pitting this kind of implementation against the most common and basic implementation, two AOP (see http://en.wikipedia.org/wiki/Aspect-oriented_programming) implementations (one using IL weaving and another using a dynamic proxy) and the usage of dependency properties. Dependency properties may seem a little out of place, but they are one of the common alternatives to using the INotifyPropertyChanged.

The main reasons to research for different INPC implementations (the aforementioned boringness and verbosity) should obviously be taken into account. Most developers don't like that they can't use the simpler syntax of automatic properties if the want to use INPC.
It's not my objective to discuss the advantages and disadvantages of each, as you can find easily find several articles that delve deep into that subject. However, there are a few points we should keep in mind when choosing the kind of implementation to use. 
A perfectly good example are the disadvantages of using dependency properties: the need of inheriting from DependencyObject and the fact that these properties can't be changed from non-UI dispatcher threads. These may be two show-stoppers depending on your situation. The first also applies to the usage of expression trees. If your viewmodels are depending on some kind of ViewModelBase class then, that's not much of a fuss, but if you wish to achieve some kind of Naked MVVM implementation (see http://blog.vuscode.com/malovicn/archive/2010/11/07/naked-mvvm-simplest-possible-mvvm-approach.aspx) than you can't rely on a base class. Anyway, if you can avoid it, there's no need to burn your base class (see http://www.artima.com/intv/dotnet.html). 

On the other hand, most AOP approaches only make sense if you're using an IOC container to resolve your viewmodels. This is due to the fact that you can't instantiate your viewmodel class directly, you'll need to call a method that creates a proxy (where the INPC is injected) for your viewmodel. One of the AOP approaches (the one using PostSharp) we're using here avoids this by injecting the INPC in your class in a post-build action through IL weaving (see http://www.sharpcrafters.com/aop.net/msil-injection).

The Test

The test is pretty simple. Each of the implementations resides in a separate class which has the integer property (conveniently named "Property") we'll be using in the test. This property will be assigned 200.000 times in a cycle and we'll be controlling the time it takes for this cycle to complete. We'll also make sure that the PropertyChanged event is handled by an event handler that does absolutely nothing (we just want to measure the event handler invocation time, not the time the event handler takes to execute, so we're making it as simple as possible).

Example source for a specific test:

I've shown the example of the PostSharp implementation because the AOP test implementations require you to add the event handler through reflection, as the event doesn't exist at compile time. That's the only difference from the non-AOP implementations. Notice that you won't need to do this in real-life applications because you won't be registering explicitly the PropertyChanged event, that's the job of the framework's binding mechanism.
Also note that in the Castle Dynamic Proxy implementation, the instantiation of the test class would be replaced by a call to create the proxy (which, as stated above, would not be visible if we were using an IOC container to resolve the class)

Test Results

Here's the code to the implementations used in the test, which by the way, I'm not claiming ownership for, I've just gathered and altered them slightly where needed.
Common INPC implementation (which I'm calling the "Plain old" way)

Expression Trees implementation

Dependency Properties implementation

PostSharp AOP implementation

Castle Dynamic Proxy AOP implementation

After this, I think it's safe to conclude that the Expression trees implementation implies a severe performance penalty and although it's far simpler than the "Plain old" way of doing it, it still loses in simplicity when compared to the AOP implementations. That said, I should say that I've always been a fan of PostSharp and I currently consider it to be the best way of implementing INPC, although it is a payed tool.

1 comentário:

Matthieu Nicolescu disse...

Thanks for you great article !

I Just posted another solution with DLR (.NET 4.0, dynamic object) : http://www.using-system.net/article-silverlight-inotifypropertychanged-dynamic-object-aop-68082929.html