Java循环效率(“for”与“foreach”)

时间:2012-02-10 10:43:44

标签: java performance for-loop foreach

(那些熟悉JVM编译和优化技巧的人的问题......: - )

是否有任何“for”和“foreach”模式明显优于其他模式?

考虑以下两个例子:

public void forLoop(String[] text)
{
    if (text != null)
    {
        for (int i=0; i<text.length; i++)
        {
            // Do something with text[i]
        }
    }
}

public void foreachLoop(String[] text)
{
    if (text != null)
    {
        for (String s : text)
        {
            // Do something with s, exactly as with text[i]
        }
    }
}

forLoopforeachLoop更快还是慢?

假设在这两种情况下text数组都不需要进行任何健全性检查,是否有明显的赢家或者仍然距离太近而不能打电话?

编辑:如某些答案中所述,数组的性能应该相同,而“foreach”模式对于像List这样的抽象数据类型可能稍微好一些。另请参阅讨论主题的this answer

5 个答案:

答案 0 :(得分:61)

来自section 14.14.2 of the JLS

  

否则,Expression必须具有数组类型T []。设L1 ... Lm是紧接在增强的for语句之前的(可能是空的)标签序列。然后,增强的for语句的含义由以下基本语句给出:

T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
        VariableModifiersopt Type Identifier = a[i];
        Statement
}

换句话说,我希望它们最终被编译成相同的代码。

肯定有明显的赢家:增强的for循环更具可读性。这应该是您最关心的问题 - 当您证明最易读的形式没有达到您想要的效果时,您甚至应该考虑微观优化这类事情。

答案 1 :(得分:4)

您可以编写自己的简单测试,测量执行时间。

long start = System.currentTimeMillis();
forLoop(text);
long end = System.currentTimeMillis();
long result = end - start;

结果是执行时间。

答案 2 :(得分:3)

由于您使用的是array类型,性能差异无关紧要。通过optimization渠道后,他们最终会获得相同的效果。

但是如果你使用像List这样的ADT,那么forEachLoop显然是与多个get(i)调用相比的最佳选择。

答案 3 :(得分:3)

除非您知道性能问题,否则您应该选择几乎每次都更具可读性的选项。

在这种情况下,我会说他们保证是一样的。

唯一的区别是你额外检查text.length,这可能会更慢,而不是更快。

我还要确保文本永远不会为静态。例如使用@NotNull注释。最好在编译/构建时捕获这些问题(并且会更快)

答案 4 :(得分:1)

即使对于数组,使用for-each循环也没有性能损失。实际上,在某些情况下,它可能比普通的for循环提供轻微的性能优势,因为它只计算一次数组索引的限制。有关详细信息,请参阅此post