Недавно я оптимизировал/протестировал некоторый код и наткнулся на этот метод:
public void SomeMethod(Type messageType)
{
if (messageType == typeof(BroadcastMessage))
{
// ...
}
else if (messageType == typeof(DirectMessage))
{
// ...
}
else if (messageType == typeof(ClientListRequest))
{
// ...
}
}
Это вызывается из цикла, критичного к производительности, в другом месте, поэтому я естественно предположил, что все эти вызовы typeof(...)
добавляли ненужные накладные расходы (я знаю, что это микрооптимизация) и могли быть перемещены в частные поля в классе. (Я знаю, что есть лучшие способы реорганизовать этот код, однако я все еще хотел бы знать, что здесь происходит.)
Согласно моему тесту, это совсем не так (используется BenchmarkDotNet).
[DisassemblyDiagnoser(printAsm: true, printSource: true)]
[RyuJitX64Job]
public class Tests
{
private Type a = typeof(string);
private Type b = typeof(int);
[Benchmark]
public bool F1()
{
return a == typeof(int);
}
[Benchmark]
public bool F2()
{
return a == b;
}
}
Результаты на моей машине (Window 10 x64,.NET 4.7.2, RyuJIT, Release build):
Функции, скомпилированные до ASM:
F1
mov rcx,offset mscorlib_ni+0x729e10
call clr!InstallCustomModule+0x2320
mov rcx,qword ptr [rsp+30h]
cmp qword ptr [rcx+8],rax
sete al
movzx eax,al
F2
mov qword ptr [rsp+30h],rcx
mov rcx,qword ptr [rcx+8]
mov rdx,qword ptr [rsp+30h]
mov rdx,qword ptr [rdx+10h]
call System.Type.op_Equality(System.Type, System.Type)
movzx eax,al
Я не знаю, как интерпретировать ASM, поэтому не могу понять значение происходящего здесь. В скорлупе ореха почему F1 быстрее?