性能是Java foreach循环对重复执行的过度杀伤力
我同意foreach循环减少了输入,并且有利于可读性
通过一点备份,我就可以开发低延迟的应用程序,每秒可以接收到100万个数据包。遍历一百万个数据包,并将这些信息发送给它的侦听器。我使用foreach循环遍历侦听器集
在分析过程中,我发现有很多迭代器对象被创建来执行foreach循环。将foreach循环转换为基于索引的foreach,我发现通过减少GC数量和增加应用程序吞吐量,在那里创建的对象数量大幅下降
编辑:(抱歉,让这个问题更清楚) 例如,我有一个监听器列表(固定大小),我每秒循环这个forloop一百万次。foreach在java中是一种过度使用吗
例如:
for(String s:listOfListeners)
{
// logic
}
相比
for (int i=0;i<listOfListeners.size();i++)
{
// logic
}
代码的概要截图
for (int cnt = 0; cnt < 1_000_000; cnt++)
{
for (String string : list_of_listeners)
{
//No Code here
}
}
# 1 楼答案
编辑:自从我写下我的答案以来,这个问题发生了很大的变化,以至于我现在不确定我在回答什么
如果是链表,使用
list.get(i)
查找内容实际上会慢很多,因为每次查找都必须遍历列表,而迭代器会记住位置例如:
所以要做一个完整的循环,实际上是以这种方式在元素上循环:
# 2 楼答案
这个比较公平吗?您正在比较使用
Iterator
与使用get(index)
此外,每个循环只会创建一个额外的
Iterator
。除非Iterator
本身由于某种原因效率低下,否则您应该会看到类似的性能# 3 楼答案
编辑:回答一个截然不同的问题:
这要看情况了——你的分析是否真的表明额外的分配是显著的?Java分配器和垃圾收集器每秒可以做大量的工作
换句话说,你的步骤应该是:
也许在你的例子中,增强的for循环是非常重要的。但我不认为是这样,也不认为每秒创造100万个对象是有意义的。我会在…前后测量有意义的指标。。。在做任何其他事情之前,确保你有具体的绩效目标,否则你就不知道什么时候停止微观优化
所以你要创建一个迭代器对象,但是你要执行循环体一百万次
没有?只应创建一个单个迭代器对象As per the JLS:
如您所见,它调用
iterator()
方法一次,然后在每次迭代中调用hasNext()
和next()
你认为额外的对象分配会严重影响你的性能吗
你认为可读性比性能重要多少?我会在任何有助于可读性的地方使用增强的for循环,直到它被证明是一个性能问题——我个人的经验是,无论我写什么,它都不会显著地影响性能。这并不是说所有应用程序都是这样,但默认的位置应该是在证明可读性较差的代码将显著改善情况后,只使用可读性较差的代码
# 4 楼答案
“foreach”循环只创建一个
Iterator
对象,而第二个循环不创建任何对象。如果要执行很多很多单独的循环,每个循环只执行几次,那么“foreach”可能会非常昂贵。否则,这就是微观优化# 5 楼答案
我认为你不应该担心这里的效率
大部分时间都被实际的应用程序逻辑所消耗(在本例中,是由您在循环中所做的事情)
所以,我不会担心你在这里为方便而付出的代价