I see code similar to the following sprinkled about some native WPF controls:
static MyControl {
Type typeFromHandle = typeof(MyControl);
// Which is used in various places
SomeProperty.OverrideMetadata(typeFromHandle, ...);
CommandManager.RegisterClassInputBinding(typeFromHandle, ...);
EventManager.RegisterClassHandler(typeFromHandle, ...);
}
Seems like the following code would have the same performance:
static MyControl {
SomeProperty.OverrideMetadata(typeof(MyControl), ...);
CommandManager.RegisterClassInputBinding(typeof(MyControl), ...);
EventManager.RegisterClassHandler(typeof(MyControl), ...);
}
Does this approach offer any benefit performance wise when JIT-ing the code or during runtime?
Short answer
Yes, it is more optimal, but no, you shouldn't use it, as in almost every case it is a premature optimization. If anything, use it as a way to maintain readability in code if you use typeof(MyControl)
many times.
Long answer
If you look at the IL produced from a typeof(MyControl)
statement in C#, you see the following:
IL_0001: ldtoken [mscorlib]MyControl
IL_0006: call class [mscorlib]System.Type
[mscorlib]System.Type::GetTypeFromHandle(
valuetype [mscorlib]System.RuntimeTypeHandle)
These instructions do the following:
RuntimeTypeHandle
(the ldtoken
IL instruction) onto the stack (the CLR one, not C#/.NET concept of one).Type
from the RuntimeTypeHandle
(the call to Type.GetTypeFromHandle
).Compare this to assigning a Type variable type with one stored in an instance:
IL_0014: ldloc.2
Note, the location (1, 2, etc.) will vary depending on other variables, but ultimately, it is a load of a reference type.
Comparing the two, the call to an already-assigned variable is always going to be faster. The first has to load the type handle and then it has to call a method in order to resolve the handle into a Type
; the second method is just a reference to a local variable.
However, like most other posts, this could most definitely be considered a case of premature optimization, so I would suggest not looking to do this if you think that your code is underperforming.
The argument can be made that it is better from a code reuse standpoint, as if you had to change the type, you would change it in less places; you won't be awash in a sea of typeof
statements.
Finally, in regards to WPF, this is something that they had to do, given the requirements for performance (as any UI system has); WPF has a tremendous amount of managed objects, many more compared to Windows Forms and has to take into account the performance of those objects so that it can render the UI as quick as possible.
As a result, you would see something like this:
private static readonly object TrueObject = true;
private static readonly object FalseObject = false;
// Later on.
DoSomething(condition ? TrueObject : FalseObject);
// Where
void DoSomething(object value)
{
// Compare to true/false objects.
if (value == TrueObject)
{
// True case.
}
else if (value == FalseObject)
{
// False case.
}
else
{
// Invalid.
throw new InvalidOperationException();
}
}
The reason for this is simple; most of WPF exposes properties/methods with objects as parameters instead of strongly-typed values. When value types are involved, it can involve a tremendous amount of boxing/unboxing.
In order to get around this, they have a single instance which is boxed/unboxed when they know exactly which values are going to be boxed/unboxed; with a bool
, it's easy, there is only true
and false
.
Again, I wouldn't necessarily recommend this approach for almost any system, but for some systems, it makes sense.
In your case, I'd simply assign the type to a variable, only for readability purposes, not for performance. If you have performance issues, look at the overall process first, isolate through measurements, and then proceed from there.
Caching of typeof
will give you a small performance boost. The following page gives the benchmarks:
Typeof expression used: 2.55 ns
Type object cached: 0.64 ns
If you typeof
a lot, or care about nanoseconds, then this might matter to you!
It's unlikely you'll write code where the performance of typeof is significant so you should choose the style of code that is most clear and maintainable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With