绕过变量的影响
impact of bypassing variables
我不知道搜索这个问题的正确方法,但这是我经常做的事情,想弄清楚我是否一直在默默地潜入我的代码。是不是这样:
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 位。
让我们看一下,很容易算出来
你可以在两者中看到,debug/release build,两者给出的结果几乎相同。
对于第二种方法,它将创建一个临时变量,其作用与第一种方法Int32 z = x+y;
完全相同
调试方法 1(第一个代码片段)
.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
调试方法 2(第二个代码片段)
.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[=11=][=11=]00
)
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[=11=][=11=]00
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 方法 1(第一个代码片段)
.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 方法 2(第二个代码片段)
.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[=13=][=13=]00
)
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[=13=][=13=]00
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
我不知道搜索这个问题的正确方法,但这是我经常做的事情,想弄清楚我是否一直在默默地潜入我的代码。是不是这样:
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 位。
让我们看一下,很容易算出来
你可以在两者中看到,debug/release build,两者给出的结果几乎相同。
对于第二种方法,它将创建一个临时变量,其作用与第一种方法Int32 z = x+y;
完全相同
调试方法 1(第一个代码片段)
.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
调试方法 2(第二个代码片段)
.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[=11=][=11=]00
)
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[=11=][=11=]00
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 方法 1(第一个代码片段)
.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 方法 2(第二个代码片段)
.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[=13=][=13=]00
)
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[=13=][=13=]00
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