In my previous post I talked about creating typed delegate factories, towards the end of the post I talked about optimising the performance by avoiding boxing when passing value type parameters around. My premise was that if we could use generics to select strongly typed method signatures for the method that constructs the type we could avoid the boxing and unboxing of value types. I think outside of dependencies, the most common constructor arguments is going to be value types. But I was wrong.
It all boils down to Constructor.Invoke, this is the method my tiny dependency injection framework uses to create new instances of objects from the container. Its only signature takes params object so all our hard work is useless because the values will be boxed for this call.
The biggest thing I was wrong about, though, was that reflection is quicker than boxing. Lets look at the timing of the reflective generic approach:
So generating the factory takes 79ms when you reflect over the type and remove any generics. But what about calling using params object.
This takes 31ms to create the factory. So it is quite clear that, at least upfront, using the param approach is substantially quicker. One thing I will point out is, the tests didn’t use the factories to create any types. But the values will still be boxed when passed to the invoke method so I would still expect the second method to be more performant.
My point is that we need to look more closely at how we are going to use the code and if there is any optimisation, like caching the generated delegates, that would speed up calls after taking an initial hit. If we didn’t need to make the call Constructor.Invoke would the second approach still be quicker overall in our application?