关于编译输出,您推断的逐步过程都不正确。 CLR 是一个堆栈机器,由于一次将所有四个相加的代码并不表示需要将中间总计作为命名变量单独分配,因此它会在适当的位置更新运行总计(或者更确切地说,弹出并推送顶部堆栈元素)。
您的两个逐步版本都需要相同数量的实际操作;一元加法版本只需要少一个局部变量分配。
以下是通过将四个输入复数相加的三种不同方法生成的实际 IL。请注意,在我的版本中,我将 Complex 类(我假设您从 How to: Use Operator Overloading to Create a Complex Number Class (C# Programming Guide) 提升)更改为保存两个 double 值而不是两个 ints。为简洁起见,我在 C# 和 IL 代码中都省略了 c1..c4 的声明。简而言之,两种推断的逐步方法都需要两个额外的stloc.s(将一个值推送到变量列表)和ldloc.s(从变量列表中检索一个值)调用。
原文:将所有四个连续添加:
C#:
Complex csum = c1 + c2 + c3 + c4;
IL:
// MultipleAdd : 5 Locals, maxstack 3
IL_0068: nop
IL_0069: ldloc.0
IL_006a: ldloc.1
IL_006b: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_0070: ldloc.2
IL_0071: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_0076: ldloc.3
IL_0077: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_007c: stloc.s csum
IL_007e: ret
推论 1:三个二进制加法
C#:
Complex ct1 = c1 + c2;
Complex ct2 = ct1 + c3;
Complex csum = ct2 + c4;
IL:
// BinaryAdd : 7 Locals, maxstack 3
IL_0068: nop
IL_0069: ldloc.0
IL_006a: ldloc.1
IL_006b: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_0070: stloc.s ct1
IL_0072: ldloc.s ct1
IL_0074: ldloc.2
IL_0075: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_007a: stloc.s ct2
IL_007c: ldloc.s ct2
IL_007e: ldloc.3
IL_007f: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_0084: stloc.s csum
IL_0086: ret
推理 2:一元加法
C#:
Complex ct = c1 + c2;
ct += c3;
Complex csum = ct + c4;
IL:
// UnaryAdd : 6 Locals, maxstack 3
IL_0068: nop
IL_0069: ldloc.0
IL_006a: ldloc.1
IL_006b: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_0070: stloc.s ct
IL_0072: ldloc.s ct
IL_0074: ldloc.2
IL_0075: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_007a: stloc.s ct
IL_007c: ldloc.s ct
IL_007e: ldloc.3
IL_007f: call valuetype Test.Complex Test.Complex::op_Addition(valuetype Test.Complex,
valuetype Test.Complex)
IL_0084: stloc.s csum
IL_0086: ret