Question

Supposing I have a class MyType:

sealed class MyType
{
    static Type typeReference = typeof(MyType);
    //...
}

Given the following code:

var instance = new MyType();
var type1 = instance.GetType();
var type2 = typeof(MyType);
var type3 = typeReference;

Which of these variable assignments would be the most efficient?

Is performance of GetType() or typeof() concerning enough that it would be beneficial to save off the type in a static field?

Was it helpful?

Solution

typeof(SomeType) is a simple metadata token lookup

GetType() is a virtual call; on the plus side you'll get the derived type if it is a subclass, but on the minus side you'll get the derived class if it is a subclass. If you see what I mean. Additionally, GetType() requires boxing for structs, and doesn't work well for nullable structs.

If you know the type at compiletime, use typeof().

OTHER TIPS

I would go with type2. It doesn't require instantiating an instance to get the type. And it's the most human readable.

The only way to find out is to measure.

The "type1" variant isn't reliable or recommended in any way, since not all types can be constructed. Even worse, it allocates memory that will need to be garbage collector and invokes the object constructors.

For the remaining two options, on my machine "type3" is about twice as fast as "type1" in both debug and release modes. Remember that this is only true for my test - the results may not be true for other processor types, machine types, compilers, or .NET versions.

        var sw = System.Diagnostics.Stopwatch.StartNew();
        for (int i = 0; i < 10000000; i++)
        {
            var y = typeof(Program).ToString();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

        sw.Restart();
        for (int i = 0; i < 10000000; i++)
        {
            var y = typeReference.ToString();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

That said, it's a bit alarming this question is being asked without a clear requirement. If you noticed a performance problem, you'd likely have already profiled it and know which option was better. That tells me that this is likely premature optimization - you know the saying, "premature optimization is the root of all evil".

Programming code is not measured only by performance. It's also measured by correctness, developer productivity, and maintainability. Increasing the complexity of your code without a strong reason just transfers that cost to somewhere else. What might have been a non-issue has now turned into a serious loss of productivity, both now and for future maintainers of the application.

My recommendation would be to always use the "type1" variant. The measurement code I listed isn't a real world scenario. Caching typeof to a reference variable likely has a ton of side-effects, particularly around the way .NET loads assemblies. Rather than having them load only when needed, it might end up loading them all one every use of the application - turning a theoretical performance optimization into a very real performance problem.

They're rather different.

typeof(MyType) gets a Type object describing the MyType type resolved in compile-type using the ldtoken instruction.

myInstance.GetType() gets the Type object describing the runtime type of the myInstance variable.

Both are intended for different scenarios.

You cannot use typeof(MyType) unless you know the type at the compile-time and have access to it.

You cannot use myInstance.GetType() unless you have an instance of the type.

typeof(MyType) is always more efficient, but you cannot use if you don't see the type at the compile time. You cannot use typeof(MyType) to learn the real runtime type of some variable, because you don't know the type.

Both basically the same. Although typeof can be used on a non-instance class like

typeof(MyClass);

But

MyClass.GetType();

won't even build since you need to have an instance of the class.

Long story short, they both do the same job in different context.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top