Scala For-Loop / For-Yield Optimization?

时间:2015-06-15 21:10:19

标签: scala lambda for-comprehension

在Scala中,forfor-yield循环通常会转换为使用Lambdas进行mapflatMapfilter调用的序列。由于编译器将Lambdas转换为匿名类而不是Java 8的花哨invokedynamic / LambdaMetafactory / Unsafe.defineAnonymousClass系统。这显然会为临时类及其实例带来大量开销,以及map,flatMap和filter操作的开销,这些操作通常会复制其底层集合。当通常更快的迭代方法可用时,至少在字节码级别上,有没有特别的理由使用函数方法解决问题?

例如,为什么

for {
  sl <- l
  el <- sl
  if el > 0
} println el.toString.length

翻译为

l.flatMap(sl => sl.filter(el => el > 0).foreach(el => println el.toString.length))

而不是

for (sl <- l) // Iterable for loop
{
    for (el <- sl) // Iterable for loop
    {
        println el.toString.length
    }
}

1 个答案:

答案 0 :(得分:1)

这是以这种方式实现的,因为SLS是如何定义它的。粘贴在这里的规则相当大,但它们完全包含在规范中。

For Comprehensions and For Loops

  

示例   以下代码生成1和1之间的所有数字对   n-1,其总和为素数。

for  { i <- 1 until n
       j <- 1 until i
       if isPrime(i+j)
} yield (i, j)
     

for comprehension转换为:

(1 until n)
  .flatMap {
     case i => (1 until i)
       .withFilter { j => isPrime(i+j) }
       .map { case j => (i, j) } }