使用类似的东西之间是否有任何性能差异
for(int i = 0; i < 10; i++) { ... }
和
for(int i = 0; i < 10; ++i) { ... }
还是编译器能够以在功能上等效的情况下使它们同样快的方式进行优化?
编辑:
有人问这个问题是因为我与同事进行了讨论,而不是因为我认为它在任何实际意义上都是有用的优化。它主要是学术性的。
最佳答案
在这种情况下,为++ i和i++生成的中间代码没有区别。鉴于此程序:
class Program
{
const int counter = 1024 * 1024;
static void Main(string[] args)
{
for (int i = 0; i < counter; ++i)
{
Console.WriteLine(i);
}
for (int i = 0; i < counter; i++)
{
Console.WriteLine(i);
}
}
}
对于两个循环,生成的IL代码是相同的:
IL_0000: ldc.i4.0
IL_0001: stloc.0
// Start of first loop
IL_0002: ldc.i4.0
IL_0003: stloc.0
IL_0004: br.s IL_0010
IL_0006: ldloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(int32)
IL_000c: ldloc.0
IL_000d: ldc.i4.1
IL_000e: add
IL_000f: stloc.0
IL_0010: ldloc.0
IL_0011: ldc.i4 0x100000
IL_0016: blt.s IL_0006
// Start of second loop
IL_0018: ldc.i4.0
IL_0019: stloc.0
IL_001a: br.s IL_0026
IL_001c: ldloc.0
IL_001d: call void [mscorlib]System.Console::WriteLine(int32)
IL_0022: ldloc.0
IL_0023: ldc.i4.1
IL_0024: add
IL_0025: stloc.0
IL_0026: ldloc.0
IL_0027: ldc.i4 0x100000
IL_002c: blt.s IL_001c
IL_002e: ret
也就是说,JIT编译器有可能(尽管极不可能)在某些情况下进行某些优化,从而使一个版本优于另一个版本。但是,如果有这样的优化,它可能只会影响循环的最终(或第一次)迭代。
简而言之,在您描述的循环结构中,对控制变量进行简单的前递增或后递增的运行时间没有什么区别。