2013-02-28 150 views
5

为什么斯卡拉理解性能

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)) 

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)) 

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)) 
} 

9毫秒

+0

至少编写你使用的Scala版本真的很有用。至多你的操作系统和其他相关信息。 – 2013-02-28 14:00:57

+0

我使用的是Windows 7和版本2.9.2,使用eclipse和jre7。 – Jeff 2013-02-28 14:12:57

+3

奇怪的方式寻找解决方案 - 你需要'a + b + c == 1000'为什么不只是设置'c = 1000 - a - b'? (显然这不是问题的答案....) – 2013-02-28 14:35:56

回答

13

你的理解是错误的。

for(x <- coll) if(condition) dosomething 

将转化为

coll.foreach{x => if(condition) dosomething } 

for(x <- coll if(condition)) dosomething 

这将转化为

coll.withFilter(x => condition).foreach{ x => dosomething } 

你可以看看The Scala Language Specification 6.16了解更多详情。

9

您可能需要检查this presentation (slides 13-15)了解循环如何在内部进行翻译的详细信息。

的你的例子的主要区别是:在for循环体(2例)发生器(1示例)

后者内

  • 条件

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

  • +0

    那些幻灯片甚至找到了更好的解决方案:) – Jeff 2013-02-28 14:21:21

    +0

    @Downvoter:你介意解释我的答案有什么问题吗? – bluenote10 2014-05-11 19:35:30