我正在研究Project Euler中的问题,作为学习Haskell的一种方式,我发现我的程序比同类C版本慢很多,即使在编译时也是如此.我该怎么做才能加速我的Haskell程序?
例如,我对问题14的强力解决方案是:
import Data.Int
import Data.Ord
import Data.List
searchTo = 1000000
nextNumber :: Int64 -> Int64
nextNumber n
| even n = n `div` 2
| otherwise = 3 * n + 1
sequenceLength :: Int64 -> Int
sequenceLength 1 = 1
sequenceLength n = 1 + (sequenceLength next)
where next = nextNumber n
longestSequence = maximumBy (comparing sequenceLength) [1..searchTo]
main = putStrLn $ show $ longestSequence
Run Code Online (Sandbox Code Playgroud)
这需要大约220秒,而"等效"暴力C版本只需要1.2秒.
#include <stdio.h>
int main(int argc, char **argv) …Run Code Online (Sandbox Code Playgroud) 我正在学习Haskell,使用项目Euler问题作为我的游乐场.我的Haskell程序与其他语言编写的类似程序相比有多慢,我感到震惊.我想知道我是否预测过某些东西,或者这是否是在使用Haskell时所期望的那种性能损失.
以下程序受到问题331的启发,但我在发布之前已经改变了它,所以我不会为其他人破坏任何东西.它计算在2 ^ 30 x 2 ^ 30网格上绘制的离散圆的弧长.这是一个简单的尾递归实现,我确保累积变量的更新跟踪弧长是严格的.然而,它需要将近一分半钟的时间才能完成(使用-O标志和ghc编译).
import Data.Int
arcLength :: Int64->Int64
arcLength n = arcLength' 0 (n-1) 0 0 where
arcLength' x y norm2 acc
| x > y = acc
| norm2 < 0 = arcLength' (x + 1) y (norm2 + 2*x +1) acc
| norm2 > 2*(n-1) = arcLength' (x - 1) (y-1) (norm2 - 2*(x + y) + 2) acc
| otherwise = arcLength' (x + 1) y (norm2 + 2*x + 1) $! …Run Code Online (Sandbox Code Playgroud)