Java循环效率(“for”vs.“foreach”)

Java循环效率(“for”vs.“foreach”),java,performance,for-loop,foreach,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] } } }

(对于熟悉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]
        }
    }
}
public void forLoop(字符串[]文本)
{
如果(文本!=null)
{
对于(int i=0;iFrom:

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

T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
        VariableModifiersopt Type Identifier = a[i];
        Statement
}
T[]a=表达式;
L1:L2:…Lm:
for(int i=0;i
换句话说,我希望它们最终被编译成相同的代码


<> P.>肯定有一个明确的赢家:增强的for循环更可读。这应该是你最关心的问题。当你已经证明了最可读的表单并不能达到你想要的效果时,你甚至应该考虑微优化这类事情。

< P>因为你使用的是<代码>数组< /代码>类型,性能差异WO。没关系。经过
优化
漏斗后,它们最终会提供相同的性能


但是如果您使用的是类似ADT的列表,那么与多个
get(i)
调用相比,
forEachLoop
显然是最好的选择。

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

在这种情况下,我会说它们保证是相同的

唯一的区别是您需要额外检查
text.length
,它可能会更慢,而不是更快


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

使用for-each循环没有性能损失,即使对于数组也是如此。事实上,在某些情况下,它可能比普通的for循环稍有性能优势,因为它只计算一次数组索引的限制。有关详细信息,请遵循此操作。

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

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

结果是执行时间。

还有,是的,你不应该依赖于这样的
优化
细节,你随时可能会失望。答案256859确实涵盖了我的问题,但不知怎么的,它没有在我的搜索中弹出。谢谢大家!表面上是的,但实际上有太多其他参数影响这样的测量(甚至测试执行的顺序)考虑它是可靠的。是的,测量执行时间并且应该有一定程度的有效性的测试从来都不是“简单的”。而不是推测。通过测量,你只会被误导;通过推测,你可能会大错特错。我发现foreach在执行同一代码块时的性能时间小于for loop。+1强调可读性/可理解性的重要性!@Kevin:你有可以共享的基准吗?This不是jit优化-它只是如何为数组编译循环。@JonSkeet我以为我是这样做的,但现在我无法复制前几天看到的内容。注释收回。
long start = System.currentTimeMillis();
forLoop(text);
long end = System.currentTimeMillis();
long result = end - start;