2

このコードがあれば

if ("test".Length == 4)

これを計算しLengthたり、コンパイラが計算してILコードで数値を使用したりすることはありますか?

実行時に実行された場合、そのようなものを含むコードは、数値が含まれている場合よりも遅いことを意味します。

例えば

int length = 2 + 4;

よりも速いでしょう

int length = 2 + "test".Length;

これは私が知りたいことです

編集:暴言ごとに、私はこれを自分でベンチマークしましたが、同じように高速に実行されているようですが、2つの異なるILコードを生成しているとの返信があったため、理由がわかりませんか?

では、パフォーマンスをまったく低下させることなくコードでこれを使用しても安全でしょうか?

4

2 に答える 2

3

私のプラットフォームでは、VS 2010 for .NET 4 でコンパイルされたコード、IL DASM が表示されます

デバッグ

...
IL_0001:  ldstr      "test"
IL_0006:  callvirt   instance int32 [mscorlib]System.String::get_Length()
...

リリース

...
IL_0000:  ldstr      "test"
IL_0005:  callvirt   instance int32 [mscorlib]System.String::get_Length()
...

つまり、コンパイル時の最適化はありません。ただし、CLR ジッターはこれを最適化する場合があります。このような最適化の結果は、アセンブリ コードを見ることで確認できます。結果は次のとおりです。

ここに画像の説明を入力

私のプラットフォームでは、Release for platform でコンパイルされたコードx86は実行時の比較を行っているように見え、ジッターはコードを最適化しませんでした。

私が使用したコード

class Program
{
    static void Main(string[] args)
    {
        if ("test".Length == 4) { }
    }
}

ifこれは、ブロック用に生成されたアセンブリ コードの一部です。test文字列の値はオンラインで比較されます17

if ("test".Length == 4)
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  sub         esp,8 
00000006  mov         dword ptr [ebp-4],ecx 
00000009  cmp         dword ptr ds:[00148ED4h],0 
00000010  je          00000017 
00000012  call        5D664D0A 
00000017  mov         ecx,dword ptr ds:[035F2188h] 
0000001d  cmp         dword ptr [ecx],ecx 
0000001f  call        5D4CA74B 
00000024  mov         dword ptr [ebp-8],eax 
00000027  nop
于 2013-04-04T12:39:39.370 に答える
1

LINQPad でコンパイルしたところです。生成された IL は次のとおりです。

IL_0001:  ldstr       "test"
IL_0006:  callvirt    System.String.get_Length
IL_000B:  ldc.i4.4    
IL_000C:  ceq         

したがって、実行時に行われるようです。結果は、コンパイラの最適化を有効にしても無効にしても同じです。

確かに、C# コンパイラが に変換できる2 + 4が、関数呼び出しldc.i4.6が必要な場合です。2 + "test".Lengthしかし、他の人が指摘しているように、JIT コンパイラーは、C# コンパイラーよりも多くの最適化をこのコードで実行できる可能性があります。

于 2013-04-04T12:33:01.923 に答える