gpt4 book ai didi

scala Iterator#foreach 性能问题

转载 作者:行者123 更新时间:2023-12-01 08:51:39 27 4
gpt4 key购买 nike

要迭代一个 Iterator,我们可以调用它的 foreach 或使用 while 循环。 foreach的实现是:

def foreach[U](f: A =>  U) { while (hasNext) f(next()) }

所以我认为foreach应该和while(iterator.hasNext)一样快,但是经过一些测试后,结果让我非常惊讶。

我的测试代码:

def getSize2[T](i: Iterator[T]) = {
var count = 0
val f = (a: T) => count += 1
while(i.hasNext) {
f(i.next)
}
count
}

def getSize3[T](i: Iterator[T]) = {
var count = 0
val f = (a: T) => count += 1
i.foreach(f)
count
}

很奇怪getSize2getSize3快3倍!

有人知道那里发生了什么吗?

编辑:粘贴我的测试程序

def main(args: Array[String]) {
val data = 0 to 100000000

val start2 = System.nanoTime
(0 to 100).foreach(_ => getSize2(data.iterator))
println("get size, while loop, using function: " + (System.nanoTime - start2)/1000000)

val start3 = System.nanoTime
(0 to 100).foreach(_ => getSize3(data.iterator))
println("get size, foreach: " + (System.nanoTime - start3)/1000000)

}

我的操作系统:ubuntu 12.04,scala版本:2.10.3

最佳答案

while 循环更快,因为函数调用不是免费的,并且不能总是被 JIT 编译器删除。特别是,var count 被包裹在一个匿名对象中,因此它可以从函数对象中访问它,为了真正加快速度,JIT 编译器需要解开所有内容,然后最终意识到它根本不需要匿名对象。

将函数调用的额外层添加到库中的 foreach 确实会使 JIT 编译器的分析复杂化(间接层是三层而不是两层,等等)。

关于scala Iterator#foreach 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23693221/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com