Developing on Staxmanade

Don’t forget what’s happening behind the syntactic sugar. (C# events)

In a comment posted by Lashas to the i4o project over at Codeplex (comment here), he suggested a great performance improvement where instead of assigning an event’s handler directly to a handler method callback, we assign it to a field containing the handler. Initially I was skeptical of his change until I profiled it for myself. And after thinking about it for a second it made total sense.

The original implementation of adding an event handler to the property we used the C# syntax as follows.

(item as INotifyPropertyChanged).PropertyChanged += IndexableCollection_PropertyChanged;

where “IndexableCollection_PropertyChanged” is a method defined as

private void IndexableCollection_PropertyChanged(object sender, PropertyChangedEventArgs e)
{…}

Lashas’s suggested performance improvement was to initialize a private field, assign it to the IndexableCollection_PropertyChanged and add/remove the property changed handler from the field instead of the example outlined above.

Field definitaion:

private PropertyChangedEventHandler _propertyChangedHandler;

Initialization (in the constructor of the class)

_propertyChangedHandler = IndexableCollection_PropertyChanged;

Usage then becomes

(item as INotifyPropertyChanged).PropertyChanged += _propertyChangedHandler;

Lashas reported approximately 30-40% performance improvement when adding/removing items from the collection by the suggested change.

Why is that?

Well, if you think about it, what is this line?

(item as INotifyPropertyChanged).PropertyChanged += IndexableCollection_PropertyChanged;

but just a little Syntactic Sugar on top of actually doing…

(item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler (IndexableCollection_PropertyChanged);

and by the suggested change of assigning a field to the property change we avoid all the “new PropertyChangedEventHandler(…)” calls. This object creation can happen once in the constructor of the collection and not on every add/remove of an item.

Just a good reminder that you need to constantly be aware of what is happening under the covers. The saying most complexity can be solved by another layer of abstraction can cause issues when you don’t truly understand (or at least remember) what that layer is actually doing.