What Performs Worse: Reflection or Boxing?
Asked Answered
B

5

9

I'm working on creating my own DI framework that creates delegate factories as a learning exercise. My way of building typed delegates is to use expressions to create a function that calls a static method with reference to my container and any constructor params.

This thrown up an interesting question with regards to value types. Which is the most performant:

a) Using reflection to select a static generic method with the correct number of parameters then use MakeGenericMethod to remove the generics

b) Go for the old fashion params Object[] and take the hit on boxing?

Biblioclast answered 12/2, 2010 at 22:3 Comment(6)
Any reason why this "learning exercise" doesn't involve profiling various setups to find the optimal solution? ;-) I'll still give a +1 though.Kettie
c) using an overload with generic parameters?Unific
Not really possible, Expression.Call takes a MethodInfo so you have to select the correct method with the correct types up front.Biblioclast
You can infer the correct types from the generic type parameters? typeof(T1), typeof(T2) etc...Unific
Which is slower is irrelevant. The relevant question is is either of them fast enough for your application? If it turns out that neither is fast enough for your application then knowing which is slower does not help. If it turns out that both are fast enough, then knowing which is slower is largely irrelevant.Unimproved
@Eric Lippert Thanks for commenting and I think my title is too negative, I was more interested in expanding my understanding of the performance implications of reflection v boxing to help me understand the CLR and C# better.Biblioclast
L
18

IME, boxing time is nothing compared to reflection.

Logician answered 12/2, 2010 at 22:5 Comment(0)
O
3

I'd guess that reflection would be alot slower, probably orders of magintude so.

It's pretty easy to bench though, give it a go and post your results :)

Ovoid answered 12/2, 2010 at 22:15 Comment(0)
E
3

In this case, boxing will be orders of magnitude faster than reflection.

Of course, you could always cache the reflection results.

Electromotor answered 12/2, 2010 at 22:21 Comment(0)
C
2

In general, I would say even if boxing had been slower (to an extent not noticeable), its the right way to go. Reflection is a tool to facilitate some sorta meta-programming - when you have to do some work over the code itself, and not to facilitate your applications business logic, and hence you shouldn't use it without a good reason. A programmer should think from the physical domain first. That said, in your case it probably doesn't matter since you're already going the meta way I think. Using object still gives you compile time safety to certain extent and better maintenance.

As others have said, reflection is the slower one here (unless you dont cache). Another thing that comes to boxing's favour is that you are most probably anyway boxing when dealing with reflection. The reflection API always deals with object, so if you are getting back some instance value you have to unbox. Similarly, calling GetType on a value type instance first boxes it to object which you may have to if you don't have the type argument, but only the instance.

But a better alternative is to rely on generics. Some nice patterns are detailed here.

Circumscribe answered 10/6, 2013 at 9:59 Comment(0)
A
1

If one has to process a million items, boxing each item will be less efficient than processing them without boxing, but will be much faster than using Reflection to process the type of each item.

On the other hand, in many scenarios it will be possible to process a million items of some generic type T by using Reflection once, on type T, to construct an object which can process something of type T without boxing, and then cache the result of that for the life of the program. This is how things things like EqualityComparer<T>.Default work. Such an approach can easily be more than an order of magnitude faster than boxing each item.

Anaesthesia answered 18/12, 2012 at 16:22 Comment(1)
Remember, though, that you would still need to access your reflection cache, most likely through a dictionary. I would not be surprised if a little boxing is still faster than those lookups - particularly if string keys are involved (which may or may not be the case).Colter

© 2022 - 2024 — McMap. All rights reserved.