以下是:
MyObject myVariable;
for(int i = 0; i < objects.Length, i++){
myVariable = objects[i];
// do stuff...
}
效率更高:
for(int i = 0; i < objects.Length, i++){
MyObject myVariable = objects[i];
// do stuff...
}
因为每次都不会创建一个用于保存引用的新变量? (或者编译器足够智能,只是为了使用相同的变量)..
(如果创建了一个新变量,它是否在堆上进行了malloced?)
答案 0 :(得分:62)
不,“变量”几乎完全是为程序员而存在的。您不是通过在方法中声明变量来在运行时创建任何其他工作。
理论上,当为该方法中声明的每个变量调用一个方法时,编译器将在堆栈上留出空间。因此,该方法中该变量的存在比其范围更重要。除非使用new
关键字,否则堆上没有分配空间。
实际上,编译器可以识别具有如此短范围的变量,以便它们可以存储在CPU上的寄存器中,而不需要堆栈上的空间。例如:
var a = b[c];
a.ToString();
// never access "a" again.
......将与:
相同b[c].ToString();
...因为编译器认识到它只需要存储b [c]的结果足够长时间来调用它上面的方法,所以它只能使用CPU寄存器而不是使用内存。
出于这个原因,在循环中声明变量 实际上可能导致该方法为变量分配 less 堆栈空间,具体取决于之后可能的逻辑流程。然而,这进入了巨大的微观优化,对大多数人来说没有任何意义。
由于有些人似乎仍然认为在循环中声明变量会产生一些影响,我想我需要提供证据。在LINQPad中键入以下程序。
int j;
for(int i = 0; i < 5; i++)
{
j = i;
}
......和......
for(int i = 0; i < 5; i++)
{
int j = i;
}
执行代码,然后转到IL选项卡查看生成的IL代码。这两个程序都是一样的:
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_0008
IL_0004: ldloc.0
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: ldc.i4.5
IL_000A: blt.s IL_0004
所以有无可辩驳的证据证明这在编译时没有任何区别。您将从两个程序中获得完全相同的编译IL。
答案 1 :(得分:1)
我对“问题”进行了基准测试,并同意StriplingWarrior。至少在速度上没有区别。
long start = Time();
long end = Time();
Console.WriteLine("Benchmark Runtime: " + (end - start) + " Microseconds");
for(int k = 0; k < 5; k++)
{
start = Time();
int j;
for (int i = 0; i < 900000000; i++)
{
j = i;
}
end = Time();
Console.WriteLine("Benchmark 1: " + (end - start) + " Microseconds");
}
for (int k = 0; k < 5; k++)
{
start = Time();
for (int i = 0; i < 900000000; i++)
{
int j = i;
}
end = Time();
Console.WriteLine("Benchmark 2: " + (end - start) + " Microseconds");
}
结果:
Benchmark Runtime: 1 Microseconds
Benchmark 1: 1730816 Microseconds
Benchmark 1: 1725885 Microseconds
Benchmark 1: 1725629 Microseconds
Benchmark 1: 1726052 Microseconds
Benchmark 1: 1726121 Microseconds
Benchmark 2: 1725843 Microseconds
Benchmark 2: 1725576 Microseconds
Benchmark 2: 1726233 Microseconds
Benchmark 2: 1725786 Microseconds
Benchmark 2: 1729965 Microseconds
答案 2 :(得分:-5)
简短回答,是的。
答案很长,是的,它更快,但除非重复多次,否则几乎不可察觉。 : - )
我不确定编译器是否会对其进行优化,但我对此表示怀疑,如果确实如此,那么它还是有好处的,你应该把它写成好像它一样,让它成为习惯。