Open DoctorKrolic opened 2 weeks ago
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.
Your TypeOfCheck
and IsCheck
do different things. TypeOfCheck
throws NRE on null objects, I don't think it's correct to compare their perf.
By adding 1 charachter to the input (namely ?
) the typeof
check became more than 3 times slower. I understand, that this is far less common to type check this way, but I still think the JIT should be able to put the null check first and then do the optimal type comparison
Shouldn't .GetType
be inlined here like it usually does without null-conditional operator?
e.g. ideally it could be the same as writing _secretObject != null && _secretObject.GetType() == typeof(MySealedClass);
; Benchmarks.TypeOfCheck()
mov rax,[rcx+8]
test rax,rax
je short M00_L00
mov rcx,MT_MySealedClass
cmp [rax],rcx
sete al
movzx eax,al
ret
M00_L00:
xor eax,eax
ret
; Total bytes of code 32
The problem that for:
o?.GetType() == typeof(...)
JIT ends up spilling o.GetType()
to a temp (it does so because of basic-block boundary) - this ruins the "o.GetType() == typeof()" -> o->pMethodTalbe == clsHandle
optimization. I think we should be able to fix it.
It doesn't happen for:
o != nullptr && o.GetType() == typeof(...)
Configuration
Data
Assembly:
Analysis
Adding a null check to a
typeof
via C#?.
operator seem to knock it off an optimized path (if there was no null check there wouldn't be acall System.Object.GetType()
). Since these two methods do the same thing, the perf should be identical