局部变量或类字段?

时间:2013-07-17 15:09:03

标签: c# java performance

我今天在C#和Java中阅读了post about performance improvement

我仍然坚持这个:


19。不要过度使用实例变量

使用局部变量可以提高性能。示例1中的代码执行速度比示例2中的代码快。

例1:

public void loop() {
    int j = 0;
    for ( int i = 0; i<250000;i++){
        j = j + 1;
    }
}

示例2:

int i;
public void loop() {
    int j = 0;
    for (i = 0; i<250000;i++){
        j = j + 1;
    }
}

实际上,我不明白为什么在我可以对字段进行简单访问时,每次调用loop函数时实例化一些内存并释放它应该更快。

这是纯粹的好奇心,我不是试图将变量'i'放在类的范围内:p 这是真的,使用局部变量更快吗?或者只是在某种情况下?

6 个答案:

答案 0 :(得分:10)

  1. 堆叠得更快然后堆。

    void f()
    {
        int x = 123; // <- located in stack
    }
    
    int x; // <- located in heap
    void f()
    {
        x = 123  
    }
    
  2. 不要忘记the principle of locality data。应该在CPU缓存中更好地缓存本地数据。如果数据接近,它们将完全加载到CPU缓存中,并且CPU不必从内存中获取它们。

答案 1 :(得分:6)

性能低至获取变量所需的步骤数。本地变量地址在编译时是已知的(它们是堆栈上的已知偏移量),用于访问加载对象“this”的成员以获取实际对象的地址,然后才能获取成员变量的地址。

答案 2 :(得分:4)

即使它会,但在这种情况下几乎没有可衡量的差异。 Probabbly 在第一种情况下,在处理器注册表级别上进行了一些优化,但同样:

  • 几乎无关紧要
  • 更重要的是,往往是不可预测的。

就记忆而言,它完全相同,没有任何区别。

第一种情况它通常更好:当你声明变量时它会被立即使用,这是常用的良好模式,因为它是

  • 易于理解(职责范围)
  • 简易重构

答案 3 :(得分:1)

我怀疑差异很小,但是在变量是对象成员的情况下,每次访问都需要通过this(有效)进行间接,而局部变量则不需要。

更一般地说,该对象不需要成员i,它只在循环的上下文中使用,因此在任何情况下使其在本地使用都更好。

答案 4 :(得分:1)

在C#中,另一个细微差别是生成的MSIL指令的数量(我猜它在Java中类似)。

加载实例字段需要两条指令:

ldarg.0                 // load "this" reference onto stack
ldfld   MyClass.myField // find the field and load its value

...但只需要一条指令来加载局部变量:

ldloc.0                 // load the value at index 0 from the list of local variables

答案 5 :(得分:0)

我测试了500,000次迭代的计算,其中我在本地使用了大约20个变量,并且使用了字段。局部变量测试大约是20毫秒,带有字段的测试大约是30毫秒。使用局部变量时,性能会显着提高。

性能差异是否相关,取决于项目。在您的平均业务应用程序中,性能提升可能不明显,最好是寻找可读/可维护的代码,但我正在开发声音合成软件,其中像这样的纳米优化实际上变得相关。