Aug 19 2009

Dynamic Access Method Performance Comparison

Category: AlexRobson @ 15:53

Just about any .Net developer can tell you that Reflection is slow. And they’re right. Reflection is slow compared to direct access. But just how slow is it when compared with other means of dynamic member access? I wanted some means to know, with a reasonable degree of certainty, what the most performant approach is.

Why You Should Care

You should care for several reasons, but the most compelling is that whether or not you use any of these methods directly, many libraries that you will encounter or use in your application development will use some means of dynamic member access. As an example, both original ASP.Net MVC control helpers and the new lambda driven helpers use two different means to dynamically access the value of the model. A good presentation which talks about the specific performance implications is currently hosted here at WhileTrue.

A List of Approaches

While the list of approaches I care about may not be exhaustive, I selected the following four means of dynamically accessing a type’s member:

  • Reflection
  • DynamicMethod
  • TypeDescriptor
  • LambdaCompilation

I had some pre-conceived notions about which methods I expected to perform the best and how I thought they would scale. I was a little surprised, but in the end, I was definitely correct regarding which method would be the slowest.

You Can Have It All

Before I start talking about performance specifics and provide the code I used, it’s important to note that I believe you can get the best of both worlds. The reason why member access expressions (lambda syntax) is seeing a lot of adoption is that it’s an excellent means of eliminating the use of magic strings to dynamically access type members. Two great examples that immediately come to mind for me are the Fluent maps in Fluent NHibernate and the newer MVC extension methods. The major benefits are intellisense support, compile time checking and better refactoring support. Since no one wants to give these up, I think it’s important to point out that there are ways to get these benefits regardless of which of the four approaches you use and that if you look at the code I wrote, you can see that in every case, a lambda expression is being used to specify the model property.

The Test Code

At first I tried writing some unit tests to determine which approach worked best. The very unfortunate thing I was seeing was that the unit tests are completely erratic in terms of performance; for minutes at a time one test would run fastest and then suddenly all the tests would start running consistently for completely different durations.

I quickly scrapped that idea and wrote a console application.  While I could explain it (it would take lots of typing) instead I’m going to make the source available here and provide a few screen shots.

image
image

The Results (so far…)

I don’t want to give anyone the impression that this is in anyway a definitive set of results but hopefully, will spark some additional discussion and suggestions for the best way to test performance for these kinds of issues. Reflection and TypeDescriptor appear to be the most performant approaches. I think this is due, in part, to optimizations in the framework for access to assembly metadata. Going by the results from the averages based testing:

Reflection .0049 ms / read
TypeDescriptor .0057 ms / read
DynamicMethod .1069 ms / read
Lambda Compilation .1310 ms / read

Now, I realize that the time per read seems near trivial, but realize that the *only* thing happening here is member access and nothing else. Before you decide that the performance differences don’t matter, make sure you check out the slides which show that lambda compilation in MVC creates a significant performance bottleneck.

If anything changes, I improve the tests, or get meaningful feedback I will be sure to update this posting or make new posts.

Need Feedback

If it’s obvious that I’ve made serious/obvious errors or there are ways that I can improve the tests, etc. please, please, please provide feedback to me through this blog, my email address asrobson @ gmail dot com or, if you Twitter, A_Robson is my Twitter account. If you just found this really helpful, I’d definitely appreciate feedback along those lines as well.

Tags:

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading