GetType() Vs. Is

I wrote two functions and disassembled them using Reflector:

.method private hidebysig static bool CompareWithIs(class ConsoleApplication1.A x) cil managed
{
.maxstack 2
.locals init ([0] bool flag)
L_0000: nop
L_0001: ldarg.0
L_0002: isinst ConsoleApplication1.B
L_0007: ldnull
L_0008: cgt.un
L_000a: stloc.0
L_000b: br.s L_000d
L_000d: ldloc.0
L_000e: ret
}
private static bool CompareWithIs(A x)
{
return (x is B);
}
.method private hidebysig static bool CompareByType(class ConsoleApplication1.A x) cil managed
{
.maxstack 2
.locals init ([0] bool flag)
L_0000: nop
L_0001: ldarg.0
L_0002: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_0007: ldtoken ConsoleApplication1.B
L_000c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
L_0011: ceq
L_0013: stloc.0
L_0014: br.s L_0016
L_0016: ldloc.0
L_0017: ret
}
private static bool CompareByType(A x)
{
return (x.GetType() == typeof(B));
}

Note that the two functions aren’t strictly equivalent; CompareByType only compares the immediate type; CompareWithIs does subclasses as well. I thought, CompareByType is a simpler operation; shouldn’t it be faster? In some related tests (using a different, very complicated set of classes) I found CompareByType to be significantly slower
(~13 seconds vs ~10 seconds). I guess the isinst command is optimized significantly.

Related posts: