2011-09-01 75 views
2

我来自C语言背景,所以我承认在Java中编写时我仍然在努力放弃内存管理。这里有一个问题出现了几次,我很想详细阐述一下。这里有两种方式来写相同的程序,唯一的区别是,当double[] array声明:在Java中的for循环中声明数组有多糟糕?

代码示例1

double[] array; 
for (int i=0; i<n; ++i) { 
    array = calculateSomethingAndReturnAnArray(i); 
    if (someFunctionOnArrays(array)) { 
     // DO ONE THING 
    } else { 
     // DO SOME OTHER THING 
    } 
} 

代码示例2

for (int i=0; i<n; ++i) { 
    double[] array = calculateSomethingAndReturnAnArray(i); 
    if (someFunctionOnArrays(array)) { 
     // DO ONE THING 
    } else { 
     // DO SOME OTHER THING 
    } 
} 

这里,private double[] calculateSomethingAndReturnAnArray(int i)总是返回一个相同长度的数组。我强烈反感代码示例2,因为它会为每次迭代创建一个新阵列,因为它只能覆盖现有阵列。不过,我认为这可能是我应该坐下来让Java为我处理情况的时候。

为什么选择其中一种方式的原因是什么,或者它们在Java中是否真的相同?

+6

您正在两种情况下创建一个新阵列。你只是在第一个样本中只声明一次数组(因为它只是一个引用,所以它的存储为32位)。但大概'calculateSomethingAndReturnAnArray'总是实例化一个新的数组,这是真正的成本所在。 –

+0

@Kirk ......介意拉出这个答案? – PengOne

+0

恩,@马克的答案更好。 ;) –

回答

8

没有什么特别之处阵列这里,因为你不分配为阵,你只是创建一个新的变量,它等同于:

Object foo; 
for(...){ 
    foo = func(...); 
} 

的情况下创建外部变量循环它,变量(它将保存它引用的东西的位置)将只被分配一次,在循环内部创建变量的情况下,变量可以在每次迭代中重新分配,但是我的猜测是编译器还是JIT会在优化步骤中解决这个问题。

我认为这是一个微型优化,如果你遇到了这段代码的问题,你应该根据测量结果做出决定,而不是单纯依靠规范做出决定,如果你没有遇到这段代码的问题,你应该做的语义上正确的事情,并在合理的范围内声明变量。

另请参阅similar question about best practices

+0

感谢您的解释和参考。 – PengOne

0

两者都为每次迭代创建一个新数组。它们具有相同的语义。

1

在没有初始化表达式的情况下声明本地变量将不起任何作用。工作发生在变量初始化时。

因此,以下是相同的同方面的语义和性能:

double[] array; 
for (int i=0; i<n; ++i) { 
    array = calculateSomethingAndReturnAnArray(i); 
    // ... 
} 

for (int i=0; i<n; ++i) { 
    double[] array = calculateSomethingAndReturnAnArray(i); 
    // ... 
} 

(你甚至不能纠缠,所述第一情况下允许array到后使用循环结束,为了合法,array必须在循环后有一个确定的值,除非你在声明中添加了一个初始化符double[] array = null;


为了详细说明@马克艾略特的点大约微优化:

  • 这实在是一个尝试优化,而不是一个真正的优化,因为(我注意到)它应该没有效果。

  • 即使Java编译器实际发出了一些不重要的可执行代码double[] array;,与循环体的总执行时间以及整个应用程序的整体执行时间相比,执行时间可能是微不足道的。因此,这很可能是无意义的优化。

  • 即使这是一个有价值的优化,您必须考虑您已针对特定目标平台进行了优化;即硬件和JVM版本的特定组合。这样的微观优化在其他平台上可能不是最佳的,理论上可能是反优化。

总之,如果您在编写Java代码时专注于类似的事情,您很可能会浪费您的时间。如果性能是您的应用所关注的问题,请关注MACRO级别的性能;例如诸如算法复杂性,良好的数据库/查询设计,网络交互模式等等。