好吧,所以我做了一個小的修改,似乎已經使哈斯克爾很大的不同。這是怎麼回事:項目歐拉概率10使用哈斯克爾
我實施Eratosthenes篩從項目歐勒Prob 10。這是怎麼一回事呢:
primesBelowN :: Integer -> [Integer]
primesBelowN n = 2:3:filter f [6*k+i | k <- [1..(n-1)`div`6], i <- [-1, 1]]
where f x = foldr g True [2..truncate(sqrt(fromInteger x))]
where g t ac = (x `rem` t /= 0) && ac
main = print $ sum $ primesBelowN 2000000
與GHC編譯它,我獲得8.95秒的運行時間:
$ ghc -O3 010SummationOfPrimes.hs
$ time 010SummationOfPrimes
142913828922
8.739u 0.122s 0:08.95 98.8% 0+0k 2384+0io 1pf+0w
我想我可以在g
功能採取Haskell的惰性計算的優勢,優化代碼。可以這樣做(或因此我認爲)通過簡單地將ac
作爲第一個參數&&
,因此,如果ac == False
不計算不等式:
primesBelowN :: Integer -> [Integer]
primesBelowN n = 2:3:filter f [6*k+i | k <- [1..(n-1)`div`6], i <- [-1, 1]]
where f x = foldr g True [2..truncate(sqrt(fromInteger x))]
where g t ac = ac && (x `rem` t /= 0)
main = print $ sum $ primesBelowN 2000000
出人意料的是,它使程序4X慢!。運行時現在明顯更大,爲30.94s:
$ ghc -O3 010SummationOfPrimes.hs
$ time 010SummationOfPrimes
142913828922
30.765u 0.157s 0:30.94 99.9% 0+0k 2384+0io 1pf+0w
我不知道哪裏出了問題......任何提示/建議/答案?提前致謝!
編輯
所以,我玩這個,當我摔倒了另一件事。看起來很容易地轉爲無限循環,如果我只是調節這樣我的函數:
primesBelowN :: Integer -> [Integer]
primesBelowN n = 2:3:filter f [6*k+i | k <- [1..(n-1)`div`6], i <- [-1, 1]]
where f x = foldr g True [m | m <- [2..],
m <= truncate(sqrt(fromInteger x))]
where g t ac = (x `rem` t /= 0) && ac
main = print $ sum $ primesBelowN 2000000
進程的內存只是不斷在這種情況下,以龐大的數字(80Gig之前,我殺了它)爆炸,沒有任何輸出:
$ ghc -O3 010SummationOfPrimes.hs
$ time 010SummationOfPrimes
^C20.401u 7.994s 0:28.42 99.8% 0+0k 2384+0io 1pf+0w
任何想法現在怎麼回事?
這是因爲你正在摺疊的權利,但''&&在其左側參數 –
@BenjaminHodgson護理嚴格到這種解釋一下? – Carsten
@BenjaminHodgson謝謝你的迴應,但我真的很感謝一個闡述。 Haskell新手在這裏。 :) – deejay