Answer: for performance reasons
Consider following methods
public static void TestMax()
{
int max = (int)Max(5, 10);
}
public static object Max(IComparable left, IComparable right)
{
return left.CompareTo(right) > 0 ? left : right;
}
Now let see how TestMax() is looking when compiled to IL
.method public hidebysig static void TestMax() cil managed
{
.maxstack 2
.locals init ([0] int32 max)
L_0000: nop
L_0001: ldc.i4.5
L_0002: box int32
L_0007: ldc.i4.s 10
L_0009: box int32
L_000e: call object Test.Program::Max(class [mscorlib]System.IComparable, class [mscorlib]System.IComparable)
L_0013: unbox.any int32
L_0018: stloc.0
L_0019: ret
}
So as we can see for this simple call we have two box instructions. This means that we have two heap allocations (malloc() in c).
Now lets see how generic version will behave:
public static void TestMax()
{
int max = Max(5, 10);
}
public static T Max<T>(T left, T right) where T : IComparable
{
return left.CompareTo(right) > 0 ? left : right;
}
and TestMax() in IL looks like this:
.method public hidebysig static void TestMax() cil managed
{
.maxstack 2
.locals init (
[0] int32 max)
L_0000: nop
L_0001: ldc.i4.5
L_0002: ldc.i4.s 10
L_0004: call !!0 Test.Program::Max<int32>(!!0, !!0)
L_0009: stloc.0
L_000a: ret
}
As you can see instead of box we now have ldc instructions which means that now we are allocating 2*4 bytes on the stack which is much much faster then allocation on the heap.
So the long answer is: Because by this simple tweak you can speed up your method for all struct parameters.
Brak komentarzy:
Prześlij komentarz