Which is good to use: Object.GetType() == typeof(Type) or Object is Type? [duplicate]
Asked Answered
M

1

22

I want to know that which statement is useful from a Performance Point of View whether to use

Object.GetType() == typeof(Type)

or

Object is Type
Multiply answered 7/1, 2015 at 6:1 Comment(4)
#983530Plod
It's important to understand these two are not equivalent and when dealing with inheritance or interfaces, one will return false and the other true. Bharadwaj's linked question demonstrates these differences.Cantilena
You can have actually tested this by yourself.Lactation
@t3chb0t: tests can indeed give an indication, but as you can see, the answer also provides an explanation: there exist dedicated CIL instructions for is whereas the .GetType() == is resolved by performing expensive function calls.Plausive
P
52

The second one:

Object is Type

Tested this 1'000'000'000 times with string versus int one gets:

//Release
00:00:18.1428040 //Object.GetType() == typeof(Type)
00:00:03.9791070 //Object is Type
//Debug
00:00:21.3545510 //Object.GetType() == typeof(Type)
00:00:06.2969510 //Object is Type
//Machine specs:
//Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
//6 GB RAM memory
//Ubuntu 14.04 (OS)
//Runtime: Mono JIT compiler version 3.2.8
//Compiler: Mono dmcs
//Notes: ran these with some background processes, but the difference in time
//       is significant enough I guess.

Note: There is a strong semantic difference between the two:

  • The equality == checks on type equality: in other words, if A : B than the equality test will fail for A.GetType() == typeof(B) whereas A is B will succeed.
  • If the object is null, it will throw a System.NullReferenceException. In the second case, it will return false.

This is rather logic from a compiler point-of-view: in the first variant, you query the object for its type. In case that's not really optimized, you do a function call first, that call then says it must return a pointer to the type-table.

In the second case, you omit such calls: the compiler will specialize it by returning the type-code. And if the Type is known in advance, it can even work out a very fast test for it.

Note furthermore that for some trivial cases, Object is Type can be optimized: for instance because the compiler can already derive that Object can't/is always of type Type.

More advanced

One can also analyze the CIL virtual machine source code, for the first variant, this is:

IL_0000: ldarg.0
IL_0001: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0006: ldtoken [mscorlib]System.Int32
IL_000b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0010: call bool [mscorlib]System.Type::op_Equality(class [mscorlib]System.Type, class [mscorlib]System.Type)
IL_0015: ret

For the second variant this is:

IL_0000: ldarg.0
IL_0001: isinst [mscorlib]System.Int32
IL_0006: ldnull
IL_0007: cgt.un
IL_0009: ret

(you can of course fill in other types). Now the ldarg.0 and ret are simply by-products of using a method, so one can ignore them.

What one sees is that in the first variant, one calls the GetType method explicitly and then calls the == operator. Function calls are in general expensive. In the second variant, it checks immediately for isinst. The code requires less bytes and uses less expensive methods. Although performance of course depends on the implementation of the runtime environment, I think it's rather safe to say the second variant will nearly always beat the first one on performance.

A compiler could probably specialize the first variant such that it runs as efficient as the second, but the Mono C# compiler doesn't seem to do this. Probably none of the available C# compilers will.

Plausive answered 7/1, 2015 at 6:7 Comment(10)
I can not accept this answer within 4 min?Multiply
@AmolBavannavar: that's to give other users an opportunity to come up with a better answer. And for such question, that's very likely.Plausive
but the way you answered this question is very good. It is this which I want from this thread. Got it . Thanks a lot..Multiply
You've answered this under four minutes with test measurements? That's incredible ;-)Lactation
Nice answer, also "small semantic difference" is somewhat understatement - they check completely different things for derived classes/interfaces.Provide
@AlexeiLevenkov: modified, better?Plausive
Side note: maybe you should consider copying/merging into duplicate as there is no such point of view covered there yet.Provide
@AlexeiLevenkov: well the "duplicate" deals more with the "semantical difference" whereas this question is more towards performance. Personally I think this is a difference... If you insist, indeed the answers should be merged).Plausive
Fair - I've added comment linking to this one. ... deleting unrelated comments 30...29..Provide
Doesn't this answer contradicts this one, saying simply the opposite?Repartee

© 2022 - 2024 — McMap. All rights reserved.