Java foreach循环对于重复执行来说是一种过度杀戮吗

Java foreach循环对于重复执行来说是一种过度杀戮吗,java,performance,for-loop,foreach,garbage-collection,Java,Performance,For Loop,Foreach,Garbage Collection,我同意foreach循环减少了输入,并且有利于可读性 只要做一点备份,我就可以进行低延迟应用程序开发,每秒可以接收100万个数据包进行处理。遍历一百万个数据包并将这些信息发送给其侦听器。我使用foreach循环遍历侦听器集 在进行分析时,我发现有很多迭代器对象是为执行foreach循环而创建的。将foreach循环转换为基于索引的foreach,我发现通过减少GC数量和增加应用程序吞吐量,在那里创建的对象数量大幅下降 编辑:(很抱歉混淆,让这个问题更清楚) 例如,我有一个监听器列表(固定大小),

我同意foreach循环减少了输入,并且有利于可读性

只要做一点备份,我就可以进行低延迟应用程序开发,每秒可以接收100万个数据包进行处理。遍历一百万个数据包并将这些信息发送给其侦听器。我使用foreach循环遍历侦听器集

在进行分析时,我发现有很多迭代器对象是为执行foreach循环而创建的。将foreach循环转换为基于索引的foreach,我发现通过减少GC数量和增加应用程序吞吐量,在那里创建的对象数量大幅下降

编辑:(很抱歉混淆,让这个问题更清楚) 例如,我有一个监听器列表(固定大小),我每秒循环这个forloop一百万次。foreach在java中是一种过度使用吗

例如:

for(String s:listOfListeners)
{
   // logic
}
list.get(0) will get the first element
list.get(1) will first get the first element to find pointer to the next
list.get(2) will first get the first element, then go to the second and then to the third
etc.
相比

for (int i=0;i<listOfListeners.size();i++)
{
   // logic
}

for(int i=0;iEDIT):回答以下截然不同的问题:

例如,我有一个监听器列表(固定大小),我每秒循环这个forloop一百万次

这要视情况而定-您的评测是否实际表明额外的分配是重要的?Java分配器和垃圾收集器每秒可以做很多工作

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

  • 在功能需求的同时设定性能目标
  • 编写尽可能简单的代码以实现功能需求
  • 测量该代码是否满足功能要求
  • 如果没有:
    • 配置文件以确定优化的位置
    • 改变
    • 再次运行测试,看看它们是否对您的有意义的指标有显著影响(分配的对象数可能不是有意义的指标;您可以处理的侦听器数可能是有意义的指标)
    • 返回到步骤3
  • 也许在你的例子中,增强的for循环是重要的。我不会假设它是重要的,也不会假设每秒创建一百万个对象是重要的。我会在之前和之后衡量有意义的指标…并确保在做任何其他事情之前有具体的性能目标,否则你不会知道何时停止微观优化


    这个列表的大小大约有一百万个对象

    所以您创建了一个迭代器对象,但是您执行了一百万次循环体

    在进行分析时,我发现有很多迭代器对象是为了执行foreach循环而创建的

    否?只应创建一个迭代器对象:

    增强型for语句相当于以下形式的基本for语句:

    如您所见,它只调用一次
    iterator()
    方法,然后在每次迭代中对其调用
    hasNext()
    next()

    您是否认为额外的对象分配实际上会严重影响您的性能


    你认为可读性比性能更重要吗?我会在任何有助于可读性的地方使用增强的for循环,直到它被证明是一个性能问题——我个人的经验是,在我所写的任何东西中,它都不会对性能造成显著影响。这并不是说对所有应用程序都是如此,但是默认情况下,应该只使用可读性较差的代码,证明它可以显著改善情况。

    foreach循环只创建一个
    迭代器对象,而第二个循环不创建任何对象。如果要执行许多单独的循环,每个循环只执行几次,则选择“foreach”可能是不必要的昂贵。否则,这是微观优化。

    我认为您不应该担心这里的有效性

    大部分时间都被实际的应用程序逻辑所消耗(在本例中,就是您在循环中所做的事情)


    因此,我不会担心您为方便而付出的代价。

    这种比较公平吗?您使用的是
    迭代器与使用
    get(index)


    此外,每个循环只会创建一个额外的
    迭代器
    。除非
    迭代器
    本身由于某种原因效率低下,否则您应该会看到类似的性能。

    编辑:自从我写了我的答案以来,这个问题已经发生了很大的变化,我现在不确定我在回答什么

    如果是链表,那么使用
    list.get(i)
    查找内容实际上会慢很多,因为每次查找都必须遍历列表,而迭代器会记住位置

    例如:

    for(String s:listOfListeners)
    {
       // logic
    }
    
    list.get(0) will get the first element
    list.get(1) will first get the first element to find pointer to the next
    list.get(2) will first get the first element, then go to the second and then to the third
    etc.
    
    因此,要进行完整循环,实际上是以这种方式在元素上循环:

    0
    0->1
    0->1->2
    0->1->2->3
    etc.
    

    嗯,我可能错了,但我认为大多数人并没有仔细阅读他不清楚的问题。事实上,他调用这个循环1000000次,因为这个循环只针对一组侦听器。@Jonskeet让我稍微改变一下。foreach的迭代是在一个方法中,即callForEach(列表l)我将列表作为参数传递。元素不断添加到此列表中,每次添加元素到此列表中都会调用方法callForEach(list l)在这种情况下,它不是为调用创建了一个迭代器对象吗?@AK4749:我已经仔细阅读了好几次,它对我来说仍然非常不清楚。但是如果列表的大小是100万个对象,那么在对其进行迭代时,创建的迭代器不太可能成为瓶颈。@srujangulla:不要添加注释-编辑你的问题在上,这是非常不清楚的。不要描述你的代码-把它包括在问题中。但是你需要理解执行一个增强的for循环只会创建一个迭代器。是的,他使用“list”两次-一次是针对数据包,一次是针对听众的代码。但是是的,毫无疑问,这是最重要的一点,从中可以得出他的答案。是的,