2013-02-28 198 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