【问题标题】:Java loop efficiency ("for" vs. "foreach") [duplicate]Java循环效率(“for”与“foreach”)[重复]
【发布时间】:2012-03-02 20:17:51
【问题描述】:

(对于那些熟悉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”模式对于像列表这样的抽象数据类型可能会稍微好一些。另请参阅讨论该主题的this answer

【问题讨论】:

  • Answer 256859 确实涵盖了我的问题,但不知何故它没有出现在我所做的搜索中。谢谢大家!

标签: java performance for-loop foreach


【解决方案1】:

来自section 14.14.2 of the JLS

否则,表达式必须具有数组类型 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
}

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

绝对有一个明显的赢家:增强的 for 循环更具可读性。这应该是您最关心的问题 - 您甚至应该考虑在您证明最易读的表单没有达到您想要的效果时,才对这类事情进行微优化。

【讨论】:

  • +1 强调可读性/可理解性的重要性!
  • @Kevin:你有可以分享的基准吗?这不是 jit 优化 - 它只是为数组编译循环的方式。
  • @JonSkeet 我以为我做到了,但现在我无法复制前几天看到的内容。评论已撤消。
【解决方案2】:

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

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

结果是执行时间。

【讨论】:

  • 看似是的,但实际上有太多其他参数会影响这种测量(甚至是执行测试的顺序),以至于不能认为它是可靠的。
  • 是的,测量执行时间并应具有一定有效性的测试从来都不是“简单的”。
  • @PNS:测量(在现实情况下)总比推测好。通过测量,您只会被误导。有了猜测,你可能会大错特错
  • 我发现在执行相同的代码块时,foreach 的执行时间小于 for 循环。
【解决方案3】:

由于您使用的是array 类型,因此性能差异并不重要。在通过optimization 漏斗之后,他们最终会给出相同的性能。

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

【讨论】:

  • 另外,是的,你不应该依赖这样的optimization细节,你随时可能会失望。
【解决方案4】:

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

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

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

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

【讨论】:

    【解决方案5】:

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

    【讨论】:

      猜你喜欢
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 2015-07-12
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      相关资源
      最近更新 更多