プロファイル(new)その2

C#はMSIL(CIL)という中間言語に変換してから各プラットフォーム用に実行ファイルを作成します。
C#で作成したexeファイルを逆アセンブルかけて、MSILを見ることができるので、設定してみましょう。

まずは、自分のWindowsの中に「ildasm.exe」を探します、そしてVS.NETの[ツール]の[外部ツール]を選択し以下のように設定します。

・タイトルに今回は「ILDASM」を設定
・コマンドには「ildasm.exe」をフルパスで設定してください。
・引数には「$(TargetPath)」を設定してください。
そして、逆アセンブルするには[ツール]に[ILDASM]が選択できるようになります、それを踏まえ、前回作成したプログラムを比較したいと思います。
■Type2

        private void timeTest()
        {
            int[] iData = new int[100];
            for (int i = 0; i < 1000000; i++)
            {
                for (int j = 0; j < 100; j++)
                    iData[j] = j;
            }
        }
.method private hidebysig instance void  timeTest() cil managed
{
  // コード サイズ       42 (0x2a)
  .maxstack  3
  .locals init ([0] int32[] iData,
           [1] int32 i,
           [2] int32 j)
  IL_0000:  ldc.i4.s   100
  IL_0002:  newarr     [mscorlib]System.Int32
  IL_0007:  stloc.0
  IL_0008:  ldc.i4.0
  IL_0009:  stloc.1
  IL_000a:  br.s       IL_0021
  IL_000c:  ldc.i4.0
  IL_000d:  stloc.2
  IL_000e:  br.s       IL_0018
  IL_0010:  ldloc.0
  IL_0011:  ldloc.2
  IL_0012:  ldloc.2
  IL_0013:  stelem.i4
  IL_0014:  ldloc.2
  IL_0015:  ldc.i4.1
  IL_0016:  add
  IL_0017:  stloc.2
  IL_0018:  ldloc.2
  IL_0019:  ldc.i4.s   100
  IL_001b:  blt.s      IL_0010
  IL_001d:  ldloc.1
  IL_001e:  ldc.i4.1
  IL_001f:  add
  IL_0020:  stloc.1
  IL_0021:  ldloc.1
  IL_0022:  ldc.i4     0xf4240
  IL_0027:  blt.s      IL_000c
  IL_0029:  ret
} // end of method Game1::timeTest

■Type3

        private int[] iData = new int[100];
        private void timeTest()
        {
            for (int i = 0; i < 1000000; i++)
            {
                for (int j = 0; j < 100; j++)
                    iData[j] = j;
            }
        }
.method private hidebysig instance void  timeTest() cil managed
{
  // コード サイズ       39 (0x27)
  .maxstack  3
  .locals init ([0] int32 i,
           [1] int32 j)
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  IL_0002:  br.s       IL_001e
  IL_0004:  ldc.i4.0
  IL_0005:  stloc.1
  IL_0006:  br.s       IL_0015
  IL_0008:  ldarg.0
  IL_0009:  ldfld      int32[] Profiler.Game1::iData
  IL_000e:  ldloc.1
  IL_000f:  ldloc.1
  IL_0010:  stelem.i4
  IL_0011:  ldloc.1
  IL_0012:  ldc.i4.1
  IL_0013:  add
  IL_0014:  stloc.1
  IL_0015:  ldloc.1
  IL_0016:  ldc.i4.s   100
  IL_0018:  blt.s      IL_0008
  IL_001a:  ldloc.0
  IL_001b:  ldc.i4.1
  IL_001c:  add
  IL_001d:  stloc.0
  IL_001e:  ldloc.0
  IL_001f:  ldc.i4     0xf4240
  IL_0024:  blt.s      IL_0004
  IL_0026:  ret
} // end of method Game1::timeTest

■Type4

        private void timeTest()
        {
            int[] pData = iData;
            for (int i = 0; i < 1000000; i++)
            {
                for (int j = 0; j < 100; j++)
                    pData[j] = j;
            }
        }
.method private hidebysig instance void  timeTest() cil managed
{
  // コード サイズ       41 (0x29)
  .maxstack  3
  .locals init ([0] int32[] pData,
           [1] int32 i,
           [2] int32 j)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      int32[] Profiler.Game1::iData
  IL_0006:  stloc.0
  IL_0007:  ldc.i4.0
  IL_0008:  stloc.1
  IL_0009:  br.s       IL_0020
  IL_000b:  ldc.i4.0
  IL_000c:  stloc.2
  IL_000d:  br.s       IL_0017
  IL_000f:  ldloc.0
  IL_0010:  ldloc.2
  IL_0011:  ldloc.2
  IL_0012:  stelem.i4
  IL_0013:  ldloc.2
  IL_0014:  ldc.i4.1
  IL_0015:  add
  IL_0016:  stloc.2
  IL_0017:  ldloc.2
  IL_0018:  ldc.i4.s   100
  IL_001a:  blt.s      IL_000f
  IL_001c:  ldloc.1
  IL_001d:  ldc.i4.1
  IL_001e:  add
  IL_001f:  stloc.1
  IL_0020:  ldloc.1
  IL_0021:  ldc.i4     0xf4240
  IL_0026:  blt.s      IL_000b
  IL_0028:  ret
} // end of method Game1::timeTest

アセンブラでプログラムを書きましょうという話ではありません、ただ、どのようなコードを書けばどのような結果になるのかは意識したほうが後々、楽ができるので、いろいろとテストしてみると良いです。

for (int j = 0; j < 100; j++)
    iData[j] = j;

だけ見てみると、ローカル変数の場合

  IL_000f:  ldloc.0
  IL_0010:  ldloc.2
  IL_0011:  ldloc.2
  IL_0012:  stelem.i4
  IL_0013:  ldloc.2
  IL_0014:  ldc.i4.1
  IL_0015:  add
  IL_0016:  stloc.2
  IL_0017:  ldloc.2
  IL_0018:  ldc.i4.s   100

グローバル変数の場合

  IL_000e:  ldloc.1
  IL_000f:  ldloc.1
  IL_0010:  stelem.i4
  IL_0011:  ldloc.1
  IL_0012:  ldc.i4.1
  IL_0013:  add
  IL_0014:  stloc.1
  IL_0015:  ldloc.1
  IL_0016:  ldc.i4.s   100

なので、ちょっとはやくなるのかもしれませんね