2

単純な好奇心、このコード

    private const long constLong = 16;
    private static long instanceLong = 16;

    static long constTest()
    { 
        long i = 4;
        return i + constLong;
    }

    static long instanceTest()
    {
        long i = 4;
        return i + instanceLong;
    }

この IL を生成します。

.field private static literal int64 constLong = int64(16)
.field private static int64 instanceLong

.method private hidebysig static int64 constTest () cil managed 
{
    // Method begins at RVA 0x2068
    // Code size 9 (0x9)
    .maxstack 2
    .locals init (
        [0] int64 i
    )

    IL_0000: ldc.i4.4
    IL_0001: conv.i8
    IL_0002: stloc.0
    IL_0003: ldloc.0
    IL_0004: ldc.i4.s 16
    IL_0006: conv.i8
    IL_0007: add
    IL_0008: ret
} // end of method Program::constTest

.method private hidebysig static int64 instanceTest () cil managed 
{
    // Method begins at RVA 0x2080
    // Code size 11 (0xb)
    .maxstack 2
    .locals init (
        [0] int64 i
    )

    IL_0000: ldc.i4.4
    IL_0001: conv.i8
    IL_0002: stloc.0
    IL_0003: ldloc.0
    IL_0004: ldsfld int64 ConsoleApplication1.Program::instanceLong
    IL_0009: add
    IL_000a: ret
} // end of method Program::instanceTest

constTest() にldc.i4.sがあるのはなぜですか?

    IL_0004: ldc.i4.s 16
    IL_0006: conv.i8

ldc.i8の代わりに:

    IL_0004: ldc.i8 16

constTest() は conv.i8 を実行する必要があるためです

私が言ったように、これは純粋な好奇心です。

4

3 に答える 3

3

この方法はよりコンパクトです。ヒントについてはラベルを参照してください。

IL_0000: ldc.i4.4
IL_0001: conv.i8
IL_0002: stloc.0

これには に 1 バイト、ldc.i4.4に 1 バイト、conv.i8合計 2 バイトかかりました。

IL_0004: ldc.i4.s 16
IL_0006: conv.i8
IL_0007: add

とに 2 バイト、 に 1 バイト、合計 3 バイトかかりldc.i4.sまし16conv.i8

またldc.i8 16、命令に 1 バイト、オペランドに 4 バイト (16)、合計 5 バイトが必要です。

ただし、IL を短くしても、ネイティブが JIT (または AOT) されると、ネイティブが高速 (または低速) になるわけではないことに注意してください。

于 2013-04-07T17:16:17.033 に答える
1

最終的なマシン コードではなく、IL を見ていることに注意してください。IL の目的は、JITTER が最適な最適化を実行できるように、コード/プログラマーの意図を可能な限り正確に捉えることです。

JITTER がこれを行っていた場合は懸念がありますが、コンパイラがこれを行う場合は問題ありません。

于 2013-04-07T17:12:33.233 に答える
1

簡単な答えは、「コンパイラがコードを生成する方法です」です。実際に生成されるネイティブ コードは、32 ビットまたは 64 ビットの CPU で実行できることを覚えておく必要があります。IL はターゲット命令セットにコンパイルされるため、次のようになります。

  ldc.i4 4
  conv.i8

64 ビット CPU では単一の負荷になる可能性があります。

于 2013-04-07T17:15:27.510 に答える