gpt4 book ai didi

c# - 引用类型变量回收 - 如果在其中声明,是否在循环中的每个循环中创建一个新的引用变量?

转载 作者:IT王子 更新时间:2023-10-29 04:04:45 26 4
gpt4 key购买 nike

是以下内容:

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...
}

因为不是每次都创建一个新变量来保存引用? (或者编译器是否足够聪明,可以使用相同的变量)。

(如果创建了一个新变量,它是否分配在堆上?)

最佳答案

不,“变量”的存在几乎完全是为了程序员。通过在方法内声明变量,您不会在运行时创建任何额外的工作。

理论上,当为方法中声明的每个变量调用方法时,编译器会在堆栈上留出空间。因此,该变量在方法中的存在比它的范围更重要。除非使用 new 关键字,否则不会在堆上分配空间。

在实践中,编译器可以识别具有如此短范围的变量,以至于它们可以存储在 CPU 的寄存器中,而不需要堆栈上的空间。例如:

var a = b[c];
a.ToString();
// never access "a" again.

... 等同于:

b[c].ToString();

...因为编译器认识到它只需要将 b[c] 的结果存储足够长的时间来调用它的方法,所以它可以只使用 CPU 寄存器而不是使用内存。

出于这个原因,在循环内部声明您的变量实际上可能会导致方法为变量分配较少堆栈空间,具体取决于之后可能的逻辑流。然而,这涉及到对大多数人来说没有任何意义的巨大的微优化。

更新

既然有些人似乎仍然认为在循环中声明一个变量会有一些效果,我想我需要提供证据。在 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。

关于c# - 引用类型变量回收 - 如果在其中声明,是否在循环中的每个循环中创建一个新的引用变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7383016/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com