Scala For-Loop / For-Yield 优化?
Scala For-Loop / For-Yield Optimization?
在 Scala 中,for
和 for-yield
循环通常被转换为使用 Lambda 调用的 map
、flatMap
和 filter
调用序列。由于编译器将那里的 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
}
}
之所以以这种方式实施,是因为 SLS 就是这样定义它的。此处粘贴的规则相当多,但它们已完全包含在规范中。
For Comprehensions and For Loops
Example
The following code produces all pairs of numbers between 1 and
n−1 whose sums are prime.
for { i <- 1 until n
j <- 1 until i
if isPrime(i+j)
} yield (i, j)
The for comprehension is translated to:
(1 until n)
.flatMap {
case i => (1 until i)
.withFilter { j => isPrime(i+j) }
.map { case j => (i, j) } }
在 Scala 中,for
和 for-yield
循环通常被转换为使用 Lambda 调用的 map
、flatMap
和 filter
调用序列。由于编译器将那里的 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
}
}
之所以以这种方式实施,是因为 SLS 就是这样定义它的。此处粘贴的规则相当多,但它们已完全包含在规范中。
For Comprehensions and For Loops
Example The following code produces all pairs of numbers between 1 and n−1 whose sums are prime.
for { i <- 1 until n j <- 1 until i if isPrime(i+j) } yield (i, j)
The for comprehension is translated to:
(1 until n) .flatMap { case i => (1 until i) .withFilter { j => isPrime(i+j) } .map { case j => (i, j) } }