内部でキャストを行うプロパティを沢山呼び出すことになりそうなので、キャストしない場合とコストを比較してみた。
6倍の性能差があった。orz


まずキャストを伴わないコードをコンパイルして実行すると

public new ConcreteElement P { get { return mElement; } }

こんなコードが出てくる。

○ 00000000  push        esi
○ 00000001  mov         esi,ecx
○ 00000003  cmp         dword ptr ds:[00A78864h],0
○ 0000000a  je          00000011
× 0000000c  call        792D101E
○ 00000011  mov         eax,dword ptr [esi+8]
○ 00000014  pop         esi
○ 00000015  ret

○は実行時に通る場所。×はスキップされる場所。
今どきのCPUは各々の命令を何クロックで実行できるのかわからないので、1クロックと仮定して7クロックぐらい?

続いて、キャストを伴うコードをコンパイルしてみると

public new ConcreteElement P { get { return (ConcreteElement)mElement; } }
○ 00000000  push        edi
○ 00000001  push        esi
○ 00000002  mov         edi,ecx
○ 00000004  cmp         dword ptr ds:[00A78864h],0
○ 0000000b  je          00000012
× 0000000d  call        792D1026
○ 00000012  mov         esi,dword ptr [edi+4]
○ 00000015  test        esi,esi
○ 00000017  je          00000031
○ 00000019  cmp         dword ptr [esi],0A797A0h
○ 0000001f  jne         00000023
○ 00000021  jmp         00000031
× 00000023  mov         edx,esi
× 00000025  mov         ecx,0A797A0h
× 0000002a  call        7912A8D4
× 0000002f  mov         esi,eax
○ 00000031  mov         eax,esi
○ 00000033  pop         esi
○ 00000034  pop         edi
○ 00000035  ret

というわけで、15クロックぐらい?

んで、7:15で約2倍の時間が掛かりそう。

as キャストを忘れていたので追記

public new ConcreteElement P { get { return mElement as ConcreteElement; } }
○ 00000000  push        esi
○ 00000001  mov         esi,ecx
○ 00000003  cmp         dword ptr ds:[00A7894Ch],0
○ 0000000a  je          00000011
× 0000000c  call        792D0F5E
○ 00000011  mov         edx,dword ptr [esi+4]
○ 00000014  mov         ecx,0A79858h
○ 00000019  call        790C8E22
○ 0000001e  pop         esi
○ 0000001f  ret

実際に10億回×10回実行してみたところ

キャスト有り Asキャスト有り キャスト無し
5261.6 ms 5976.6 ms 852.3 ms

数字は 10回の平均
うげ、2倍どころではない。約6倍かぁ。

カテゴリー: 技術情報