简单的循环性能问题

时间:2011-11-28 22:32:03

标签: java php performance

假设我有一个像这样的简单PHP循环

// Bad example
$array = array('apple','banana','cucumber');
for ($i = 1; $i < count($array); $i++) {
    echo $array[$i];
}

我知道这是一种不好的做法。在循环中使用count()更好

// Nice example
$array = array('apple','banana','cucumber');
$limit = count($array);
for ($i = 1; $i < $limit; $i++) {
    // do something...
}    

在Java中,我会这样做

// Bad example?
String[] array = {"apple","banana","cucumber"};
for(int i = 0; i < array.length; i++){
    System.out.println(array[i]);
}

问题:这也不是一个坏习惯吗?或者它与下面的例子相同?

// Nice example?
String[] array = {"apple","banana","cucumber"};
int limit = array.length;
for(int i = 0; i < limit; i++){
    System.out.println(array[i]);
}

5 个答案:

答案 0 :(得分:6)

任何体面的编译器/解释器都应该自动优化第一个例子来匹配第二个例子(无论如何,从语义上讲,如果不完全是字面意义),可能是第三个匹配第四个例子。它被称为循环不变优化,其中编译器识别实体(变量,表达式等)在循环内不变(即不变)并将其删除循环外(松散地说)。

如果它曾经存在的话,那就完全可以了。

答案 1 :(得分:5)

您使用的“坏”示例并不等同,因此无法比较 - 即使它们表面上看起来如此。使用此说明:

for (initialization; termination; increment) {
    statement(s)
}

(描述了PHP和java循环),初始化语句在循环开始时执行一次。每次迭代循环都会执行终止语句和增量

终止语句中使用PHP的count是不好的原因是,对于每次迭代,都会发生count函数调用。在您的Java示例中,array.length不是函数调用,而是对公共成员的引用。因此,示例中使用的终止语句不是等效行为。我们期望函数调用比属性引用更昂贵。

任何语言的for循环的终止语句中放置函数调用(或调用屏蔽函数的属性)是不好的做法描述了循环力学。这就是使PHP示例“坏”的原因,如果你在Java中使用count - 类型的函数来循环终止语句,那也同样糟糕。那么,真正的问题是Java的Array.length是否确实掩盖了函数调用 - 答案是“不”(参见潜在的重复问题,和/或查看http://leepoint.net/notes-java/data/arrays/arrays.html

答案 2 :(得分:2)

主要区别在于count()是一个函数,而array.length是一个属性,因此与limit变量没有区别。

答案 3 :(得分:1)

它们不一样,在Java“漂亮的例子”中,你不是每次都计算数组的长度。相反,您将其存储在limit变量中并使用它来停止计算,而不是每次迭代通过for循环调用数组上的length函数的结果。

编辑:你认为“坏习惯”的两件事都是不好的做法,“好例子”是更有效的方法(至少在理论上)。但确实在实施过程中不会有任何明显的差异。

答案 4 :(得分:1)

在java中,这并不重要,数组将此属性作为常量(public final int)。 不同之处在于java数组具有固定的大小并且不能增长,因此不需要每次都可以计算元素的访问长度。

相关问题