Самый простой пример - метод Add() класса Dictionary
Ответ
Немного подробностей - несмотря на то, что в исходниках действительно нет (object), оно есть в IL.
public static void Test
после компиляции (в release!) в IL превращается в
.method public hidebysig static void Test
Обратите внимание, что никаких вызовов == уже нет. Значение в стеке - адрес объекта в памяти - просто сравнивается с 0.
Более того, boxing и проверка на null есть и после прохода JIT по коду при запуске под отладчиком:
Test(5);
01212640 mov ecx,5
01212645 call dword ptr ds:[5191C7Ch]
----
if (param == null)
01212678 push ebp
01212679 mov ebp,esp
0121267B sub esp,8
0121267E xor eax,eax
01212680 mov dword ptr [ebp-8],eax
01212683 mov dword ptr [ebp-4],ecx
01212686 cmp dword ptr ds:[5190B94h],0
0121268D je 01212694
0121268F call 7431C310
01212694 mov ecx,73273B04h
01212699 call 01182100
0121269E mov dword ptr [ebp-8],eax
012126A1 mov eax,dword ptr [ebp-8]
012126A4 mov edx,dword ptr [ebp-4]
012126A7 mov dword ptr [eax+4],edx
012126AA mov eax,dword ptr [ebp-8]
012126AD test eax,eax
012126AF jne 012126BC
{
Console.WriteLine("Never going to happen");
012126B1 mov ecx,dword ptr ds:[3D621F4h]
012126B7 call 731A023C
}
}
012126BC nop
}
}
012126BD mov esp,ebp
012126BF pop ebp
012126C0 ret
а вот запуск без отладчика полностью меняет картину. Код вида
Debugger.Launch();
Test(5);
Test("test");
на самом деле превращается в
Debugger.Launch();
041D0050 push ebp
041D0051 mov ebp,esp
041D0053 call 7386868C
Test("test");
01260058 cmp dword ptr ds:[3C82188h],0 <-- это заинлайненный if
0126005F jne 01260076
01260061 call 731A0258
Нет никакого box. Нет if. Нет даже ни одного вызова Test. Вызов с 5 удален целиком. Вызов с string test - заинлайнен.
Не заморачивайтесь и дайте JIT делать свою работу. И да, компилируйте Production сборки как Release, а не как Debug. Это сокращает жизнь переменных - и продлевает жизнь разработчика.
Комментариев нет:
Отправить комментарий