@GrabYourPitchforkshttps ://github.com/dotnet/coreclr/pull/20386でトリックを見つけました
JITはパターンを認識し、封印されたタイプ用に最適化されたコードを生成できます。
`` `C#
[MethodImpl(MethodImplOptions.NoInlining)]
public static int Is(object obj)
{{
if(objは文字列str)
str.Lengthを返します。
return 7;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static int As(object obj)
{
string str = obj as string;
if (str != null)
return str.Length;
return 7;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static int SafeUnsafe(object obj)
{
if (obj != null && obj.GetType() == typeof(string))
return Unsafe.As<string>(obj).Length;
return 7;
}
<details><summary>See the generated code</summary><p>
```ASM
; Assembly listing for method Program:Is(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
; V00 arg0 [V00,T01] ( 3, 3 ) ref -> rcx class-hnd
; V01 loc0 [V01,T02] ( 3, 2.50) ref -> rax class-hnd
;# V02 OutArgs [V02 ] ( 1, 1 ) lclBlk ( 0) [rsp+0x00]
; V03 tmp1 [V03,T00] ( 5, 6.74) ref -> rax class-hnd
;
; Lcl frame size = 0
G_M12761_IG01:
0F1F440000 nop
G_M12761_IG02:
488BC1 mov rax, rcx
4885C0 test rax, rax
7411 je SHORT G_M12761_IG03
48BA00F50A96FE7F0000 mov rdx, 0x7FFE960AF500
483910 cmp qword ptr [rax], rdx
7402 je SHORT G_M12761_IG03
33C0 xor rax, rax
G_M12761_IG03:
4885C0 test rax, rax
7404 je SHORT G_M12761_IG05
8B4008 mov eax, dword ptr [rax+8]
G_M12761_IG04:
C3 ret
G_M12761_IG05:
B807000000 mov eax, 7
G_M12761_IG06:
C3 ret
; Total bytes of code 45, prolog size 5 for method Program:Is(ref):int
; ============================================================
; Assembly listing for method Program:As(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
; V00 arg0 [V00,T01] ( 3, 3 ) ref -> rcx class-hnd
; V01 loc0 [V01,T02] ( 3, 2.50) ref -> rax class-hnd
;# V02 OutArgs [V02 ] ( 1, 1 ) lclBlk ( 0) [rsp+0x00]
; V03 tmp1 [V03,T00] ( 5, 6.74) ref -> rax class-hnd
;
; Lcl frame size = 0
G_M12497_IG01:
0F1F440000 nop
G_M12497_IG02:
488BC1 mov rax, rcx
4885C0 test rax, rax
7411 je SHORT G_M12497_IG03
48BA00F50A96FE7F0000 mov rdx, 0x7FFE960AF500
483910 cmp qword ptr [rax], rdx
7402 je SHORT G_M12497_IG03
33C0 xor rax, rax
G_M12497_IG03:
4885C0 test rax, rax
7404 je SHORT G_M12497_IG05
8B4008 mov eax, dword ptr [rax+8]
G_M12497_IG04:
C3 ret
G_M12497_IG05:
B807000000 mov eax, 7
G_M12497_IG06:
C3 ret
; Total bytes of code 45, prolog size 5 for method Program:As(ref):int
; ============================================================
; Assembly listing for method Program:SafeUnsafe(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
; V00 arg0 [V00,T00] ( 5, 4 ) ref -> rcx class-hnd
;# V01 OutArgs [V01 ] ( 1, 1 ) lclBlk ( 0) [rsp+0x00]
;
; Lcl frame size = 0
G_M6777_IG01:
0F1F440000 nop
G_M6777_IG02:
4885C9 test rcx, rcx
7413 je SHORT G_M6777_IG04
48B800F50A96FE7F0000 mov rax, 0x7FFE960AF500
483901 cmp qword ptr [rcx], rax
7504 jne SHORT G_M6777_IG04
8B4108 mov eax, dword ptr [rcx+8]
G_M6777_IG03:
C3 ret
G_M6777_IG04:
B807000000 mov eax, 7
G_M6777_IG05:
C3 ret
; Total bytes of code 35, prolog size 5 for method Program:SafeUnsafe(ref):int
; ============================================================
そして、 rax
を節約するには、
cmp qword ptr [rcx], 0x7FFE960AF500
それ以外の
mov rax, 0x7FFE960AF500
cmp qword ptr [rcx], rax
これは改善が必要な既知の領域です(dotnet / runtime#9117を参照)。
ほとんどのx64命令は、大きなリテラル定数オペランドを処理できません。そのため、上記のようにmov; cmp
が表示されます。
重複の週:)
閉鎖。
これらの種類の例があると便利です(そして思い出してください)。
すでに知られていることを報告することを心配しているので、報告を控えないでください。 見た目が似ているものが、最終的にはそれほど似ていない場合があります。
最も参考になるコメント
これらの種類の例があると便利です(そして思い出してください)。
すでに知られていることを報告することを心配しているので、報告を控えないでください。 見た目が似ているものが、最終的にはそれほど似ていない場合があります。