问题描述
如下:
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...
}
因为不是每次都创建一个新变量来保存引用?(或者编译器是否足够聪明以使用相同的变量).
because a new variable to hold a reference is not created every time? (or is the complier intelligent enough just to use the same variable)..
(如果创建了一个新变量,它是否会在堆上分配?)
(If a new variable is created is it malloced on the heap?)
推荐答案
不,变量"几乎完全是为了程序员而存在的.通过在方法内声明变量,您不会在运行时创建任何额外的工作.
No, "variables" exist almost entirely for the sake of the programmer. You're not creating any additional work at run-time by declaring the variable inside the method.
理论上,当为该方法中声明的每个变量调用方法时,编译器会在堆栈上留出空间.因此,该方法中该变量的存在将比其作用域更重要.除非使用 new
关键字,否则不会在堆上分配空间.
In theory, the compiler will set aside space on the stack when a method is called for each variable declared in that method. So the presence of that variable in the method would be more important than its scope. No space is allocated on the heap unless the new
keyword is used.
在实践中,编译器可以识别具有如此短范围的变量,它们可以存储在 CPU 上的寄存器中,而不需要堆栈上的空间.例如:
In practice, the compiler can identify variables that have such a short scope that they can be stored in a register on the CPU instead of needing space on the stack. For example:
var a = b[c];
a.ToString();
// never access "a" again.
... 等同于:
b[c].ToString();
...因为编译器认识到它只需要存储 b[c] 的结果足够长的时间来调用它的方法,所以它可以只使用 CPU 寄存器而不是使用内存.
... because the compiler recognizes that it only needs to store the result of b[c] long enough to call a method on it, so it can just use a CPU register instead of using memory.
出于这个原因,在循环中声明变量内部实际上可能会导致该方法为变量分配更少的堆栈空间,具体取决于之后可能的逻辑流程.然而,这进入了巨大的微观优化,对大多数人来说没有任何意义.
For this reason, declaring your variable inside the loop could actually cause the method to allocate less stack space for the variable, depending on the possible logic flow afterward. However, that gets into huge micro-optimization that doesn't make any sense for most people to care about.
既然有些人好像还是觉得在循环中声明一个变量有一定的作用,我想我需要提供证据.在 LINQPad 中输入以下程序.
Since some people still seem to think that declaring a variable in a loop has some effect, I guess I need to provide proof. Type the following programs into LINQPad.
int j;
for(int i = 0; i < 5; i++)
{
j = i;
}
...和...
for(int i = 0; i < 5; i++)
{
int j = i;
}
执行代码,然后进入IL选项卡查看生成的IL代码.这两个程序都是一样的:
Execute the code, then go to the IL tab to see the generated IL code. It's the same for both of these programs:
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.
So there's incontrovertible proof that this will make no difference at compile time. You'll get exactly the same compiled IL from both programs.
这篇关于引用类型变量回收 - 如果在循环中声明,是否会在循环中的每个循环中创建一个新的引用变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!