Scala用于理解性能

Jef*_*eff 6 algorithm performance scala

为什么是

for (
  a <- 1 to 1000;
  b <- 1 to 1000 - a;
  c <- 1 to 1000 - a - b;
  if (a * a + b * b == c * c && a + b + c == 1000)
) println((a, b, c, a * b * c))
Run Code Online (Sandbox Code Playgroud)

266毫秒

慢一点:

for (a <- 1 to 1000)
  for (b <- 1 to 1000 - a)
    for (c <- 1 to 1000 - a - b)
      if (a * a + b * b == c * c)
        if (a + b + c == 1000)
          println((a, b, c, a * b * c))
Run Code Online (Sandbox Code Playgroud)

62毫秒

如果我理解正确,这应该是一样的吗?


处理答案后的解决方案

for (
  a <- 1 to 1000;
  b <- 1 to (1000 - a)
) {
  val c = (1000 - a - b)
  if (a * a + b * b == c * c)
    println((a, b, c, a * b * c))
}
Run Code Online (Sandbox Code Playgroud)

9毫秒

Eas*_*sun 14

你的理解是错误的.

当条件在循环体中时会发生这种情况:

// this
for(x <- coll) if(condition) doSomething
// will translate to
coll.foreach{ x => if(condition) doSomething }
Run Code Online (Sandbox Code Playgroud)

与条件在发电机本身时相反:

// this
for(x <- coll if(condition)) dosomething
// will translate to
coll.withFilter(x => condition).foreach{ x => dosomething }
Run Code Online (Sandbox Code Playgroud)

您可以查看Scala语言规范6.16以获取更多详细信息.


blu*_*e10 10

您可能需要查看此演示文稿(幻灯片13-15),以获取有关如何在内部翻译for循环的详细信息.

您的示例的主要区别是:

  • for循环体中的条件(2.示例)
  • 发电机内的状况(例子)

后者,也称为环路滤波,在设计上带有性能缺陷.为了极大地简化发生的事情:在内部withFilter(这是翻译的第一步)Function2[Object, Boolean]创建了一个匿名的新类型函数(用于评估条件).传递给其apply函数的参数必须加框,因为它是基于的定义的Object.这种装箱/拆箱比if直接在for循环体内评估条件慢得多,这允许直接访问变量.