【问题标题】:impact of bypassing variables绕过变量的影响
【发布时间】:2015-03-01 23:25:37
【问题描述】:

我不知道搜索这个问题的正确方法,但这是我经常做的事情,我想弄清楚我是否一直在默默地潜入我的代码。是这样的:

Int32 x = 5;
Int32 y = 7;
Int32 z = x+y;

Console.Write(z.ToString());

同理:

Int32 x = 5;
Int32 y = 7;

Console.Write((x+y).ToString());

我倾向于写第一个多于第二个。它更冗长,但我发现调试它要简单得多,因为我可以看到方法的结果是什么。

  • 这些在性能或 JIT 编译器方面有什么不同吗?
  • 我使用的是值类型还是引用类型重要吗?

我正在构建和部署一个 .net 4.5 应用程序,64 位。

【问题讨论】:

  • 在遇到真正的性能问题之前,不要担心(可能)浪费纳秒。请尝试编写清晰且可维护的代码。
  • 您没有指定要在哪个编译器、运行时或目标平台上调查此问题。
  • 不要试图“帮助”编译器。任何半体面的优化 JIT 都会将你的小 sn-p 减少到相当于Console.Write("12")。当 CIL 代码转换为 JIT 的中间表示时,有关表达式是否存储在变量中的信息很可能会被丢弃。

标签: c# performance jit il


【解决方案1】:

让他们看看,很容易弄清楚那个


您可以在调试/发布版本中看到,两者都给出几乎相同的结果。

对于第二种方法,它将创建一个临时变量,该变量的作用与第一种方法的 Int32 z = x+y; 完全相同


DEBUG Method1(第一个代码sn-p)

.method private hidebysig static 
    void Method1 () cil managed 
{
    // Method begins at RVA 0x2060
    // Code size 23 (0x17)
    .maxstack 2
    .locals init (
        [0] int32 x,
        [1] int32 y,
        [2] int32 z
    )

    IL_0000: nop
    IL_0001: ldc.i4.5
    IL_0002: stloc.0
    IL_0003: ldc.i4.7
    IL_0004: stloc.1
    IL_0005: ldloc.0
    IL_0006: ldloc.1
    IL_0007: add
    IL_0008: stloc.2
    IL_0009: ldloca.s z
    IL_000b: call instance string [mscorlib]System.Int32::ToString()
    IL_0010: call void [mscorlib]System.Console::Write(string)
    IL_0015: nop
    IL_0016: ret
} // end of method Program::Method1

DEBUG Method2(第二个代码sn-p)

.method private hidebysig static 
    void Method2 () cil managed 
{
    // Method begins at RVA 0x2084
    // Code size 23 (0x17)
    .maxstack 2
    .locals init (
        [0] int32 x,
        [1] int32 y,
        [2] int32 CS$0$0000
    )

    IL_0000: nop
    IL_0001: ldc.i4.5
    IL_0002: stloc.0
    IL_0003: ldc.i4.7
    IL_0004: stloc.1
    IL_0005: ldloc.0
    IL_0006: ldloc.1
    IL_0007: add
    IL_0008: stloc.2
    IL_0009: ldloca.s CS$0$0000
    IL_000b: call instance string [mscorlib]System.Int32::ToString()
    IL_0010: call void [mscorlib]System.Console::Write(string)
    IL_0015: nop
    IL_0016: ret
} // end of method Program::Method2

RELEASE Method1(第一个代码sn-p)

.method private hidebysig static 
    void Method1 () cil managed 
{
    // Method begins at RVA 0x205c
    // Code size 21 (0x15)
    .maxstack 2
    .locals init (
        [0] int32 x,
        [1] int32 y,
        [2] int32 z
    )

    IL_0000: ldc.i4.5
    IL_0001: stloc.0
    IL_0002: ldc.i4.7
    IL_0003: stloc.1
    IL_0004: ldloc.0
    IL_0005: ldloc.1
    IL_0006: add
    IL_0007: stloc.2
    IL_0008: ldloca.s z
    IL_000a: call instance string [mscorlib]System.Int32::ToString()
    IL_000f: call void [mscorlib]System.Console::Write(string)
    IL_0014: ret
} // end of method Program::Method1

RELEASE Method2(第二个代码sn-p)

.method private hidebysig static 
    void Method2 () cil managed 
{
    // Method begins at RVA 0x2080
    // Code size 21 (0x15)
    .maxstack 2
    .locals init (
        [0] int32 x,
        [1] int32 y,
        [2] int32 CS$0$0000
    )

    IL_0000: ldc.i4.5
    IL_0001: stloc.0
    IL_0002: ldc.i4.7
    IL_0003: stloc.1
    IL_0004: ldloc.0
    IL_0005: ldloc.1
    IL_0006: add
    IL_0007: stloc.2
    IL_0008: ldloca.s CS$0$0000
    IL_000a: call instance string [mscorlib]System.Int32::ToString()
    IL_000f: call void [mscorlib]System.Console::Write(string)
    IL_0014: ret
} // end of method Program::Method2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多