I\'ve written two equivalent methods:
static bool F(T a, T b) where T : class
{
return a == b;
}
static bool F2(A a, A b)
{
return a == b;
Stop worrying about timing, worry about correctness.
Those methods are not equivalent. One of them uses class A
's operator==
and the other uses object
's operator==
.
I rewrote your test code:
var stopwatch = new Stopwatch();
var a = new A();
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 100000000; i++)
F<A>(a, a);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 100000000; i++)
F2(a, a);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Swapping the order doesn't change anything.
CIL for generic method:
L_0000: nop
L_0001: ldarg.0
L_0002: box !!T
L_0007: ldarg.1
L_0008: box !!T
L_000d: ceq
L_000f: stloc.0
L_0010: br.s L_0012
L_0012: ldloc.0
L_0013: ret
And for non-generic:
L_0000: nop
L_0001: ldarg.0
L_0002: ldarg.1
L_0003: ceq
L_0005: stloc.0
L_0006: br.s L_0008
L_0008: ldloc.0
L_0009: ret
So the boxing operation is the reason of your time difference. The question is why the boxing operation is added. Check it, Stack Overflow question Boxing when using generics in C#