以下是:
MyObject myVariable;
for(int i = 0; i < objects.Length, i++){
myVariable = objects[i];
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
效率更高:
for(int i = 0; i < objects.Length, i++){
MyObject myVariable = objects[i];
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
因为每次都不会创建一个用于保存引用的新变量?(或者编译器足够智能,只是为了使用相同的变量)..
(如果创建了一个新变量,它是否在堆上进行了malloced?)
Str*_*ior 66
不,"变量"几乎完全是为程序员而存在的.您不是通过在方法中声明变量来在运行时创建任何其他工作.
理论上,当为该方法中声明的每个变量调用一个方法时,编译器将在堆栈上留出空间.因此,该方法中该变量的存在比其范围更重要.除非使用new关键字,否则不会在堆上分配空间.
实际上,编译器可以识别具有如此短范围的变量,以便它们可以存储在CPU上的寄存器中,而不需要堆栈上的空间.例如:
var a = b[c];
a.ToString();
// never access "a" again.
Run Code Online (Sandbox Code Playgroud)
......会是这样的:
b[c].ToString();
Run Code Online (Sandbox Code Playgroud)
...因为编译器认识到它只需要存储b [c]的结果足够长时间来调用它上面的方法,所以它只能使用CPU寄存器而不是使用内存.
出于这个原因,声明你变量内部环路可能实际上导致方法分配较少的变量堆栈空间,这取决于可能的逻辑流程之后.然而,这进入了巨大的微优化,对大多数人来说没有任何意义.
由于有些人似乎仍然认为在循环中声明变量会产生一些影响,我想我需要提供证据.在LINQPad中键入以下程序.
int j;
for(int i = 0; i < 5; i++)
{
j = i;
}
Run Code Online (Sandbox Code Playgroud)
......而且......
for(int i = 0; i < 5; i++)
{
int j = i;
}
Run Code Online (Sandbox Code Playgroud)
执行代码,然后转到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
Run Code Online (Sandbox Code Playgroud)
所以有无可辩驳的证据证明这在编译时没有任何区别.您将从两个程序中获得完全相同的编译IL.
| 归档时间: |
|
| 查看次数: |
8108 次 |
| 最近记录: |