Java foreach循环是否会重复执行

Sru*_*lla 7 java performance foreach garbage-collection for-loop

我同意foreach循环减少打字并且有助于提高可读性.

一点点备份,我致力于低延迟应用程序开发,并接收每秒处理1M亿个数据包.迭代一百万个数据包并将此信息发送给其侦听器.我正在使用foreach循环来遍历一组监听器.

做分析我认为有很多Iterator对象被创建来执行foreach循环.将foreach循环转换为基于索引的foreach我观察到通过减少no而在那里创建的对象数量大幅下降.GC的增加和应用程序吞吐量的增加.

编辑 :(抱歉混淆,让这个Q更清晰)例如我有听众列表(固定大小),我循环这个forloop每秒一百万次.在Java中,foreach是一种矫枉过正吗?

例:

for(String s:listOfListeners)
{
   // logic
}
Run Code Online (Sandbox Code Playgroud)

相比

for (int i=0;i<listOfListeners.size();i++)
{
   // logic
}
Run Code Online (Sandbox Code Playgroud)

已截断的代码截图

for (int cnt = 0; cnt < 1_000_000; cnt++)
{
    for (String string : list_of_listeners)
    {
         //No Code here 
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Jon*_*eet 10

编辑:回答完全不同的问题:

例如,我有听众列表(固定大小),我每秒循环这个forloop一百万次.在Java中,foreach是一种矫枉过正吗?

这取决于 - 您的分析是否真的表明额外的分配是重要的?Java分配器和垃圾收集器每秒可以完成大量工作.

换句话说,你的步骤应该是:

  1. 设定性能目标和功能需求
  2. 编写最简单的代码来实现您的功能需求
  3. 衡量该代码是否符合功能要求
  4. 如果不是:
    • 配置文件以确定优化的位置
    • 做出改变
    • 再次运行测试以查看它们是否在您有意义的指标中产生显着差异(分配的对象数量可能不是一个有意义的指标;您可以处理的侦听器数量可能是多少)
    • 回到第3步.

也许在你的情况下,增强的for循环是重要的.我不会认为它是 - 我也不会认为每秒创建一百万个对象是重要的.我会在之前和之后测量有意义的指标...并确保在执行任何其他操作之前有具体的性能目标,否则您将不知道何时停止微优化.


列表大小约为一百万个流媒体.

所以你要创建一个迭代器对象,但是你正在执行你的循环体一百万次.

做分析我认为有很多Iterator对象被创建来执行foreach循环.

不?只有一个单一的迭代器对象应创建.根据JLS:

增强的for语句相当于表单的基本for语句:

    for (I #i = Expression.iterator(); #i.hasNext(); ) {
        VariableModifiersopt TargetType Identifier =
            (TargetType) #i.next();
        Statement
    }
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,调用该iterator()方法一次,然后调用hasNext()next()它在每次迭代.

您是否认为额外的对象分配会显着损害您的性能?

您是否重视可读性而不是性能?我采用了增强型for循环的方法,只要它有助于提高可读性,直到它被证明是一个性能问题 - 而我个人的经验是,它从未在我编写的任何内容中显着损害性能.这并不是说对于所有应用程序都是如此,但默认位置应该是在证明它将显着改善之后仅使用可读性较低的代码.


Ern*_*ill 6

"foreach"循环只创建一个Iterator对象,而第二个循环则不创建任何对象.如果你正在执行很多很多单独的循环,每个循环只执行几次,那么是的,"foreach"可能会不必要地昂贵.否则,这是微优化.