简体   繁体   English

为什么我的haskell程序太慢?

[英]Why my haskell program is too slow?

I tried to solve Problem 443 on ProjectEuler, https://projecteuler.net/problem=443 . 我试图在ProjectEuler( https://projecteuler.net/problem=443)上解决问题443。

To find pattern of g, I simply implemented g in Haskell as 为了找到g的模式,我只是在Haskell中将g实现为

g::Int->Int
g 4=13
g n=g (n-1)+n `gcd` g(n-1)

But computing list t=[gi|i<-[4..100]] takes much more than 1 second. 但是计算列表t=[gi|i<-[4..100]]花费的时间远远超过1秒。 Why this happens? 为什么会这样? Even without memoization, it takes only O(n) for each g(n). 即使没有记忆,每个g(n)也只需要O(n)。

Edit: when I tried this code in ideone, it's fine, but in my computer it's not. 编辑:当我在ideone中尝试此代码时,可以,但是在我的计算机中则不行。 Is that haskell version problem? 那是haskell版本的问题吗? I'm using version ghc 7.8.3 on Windows, while ideone using ghc 7.6. 我在Windows上使用的版本是ghc 7.8.3,而ideone使用的是ghc 7.6。

it takes only O(n) for each g(n) 每g(n)只需要O(n)

Not exactly. 不完全是。 In your recursive case 在您的递归情况下

 gn=g (n-1)+n `gcd` g(n-1) 

you are calling g twice . 你打两次 g Which means you are getting exponential runtime actually ( O(2 n ) ). 这意味着您实际上正在获得指数运行时( O(2 n ) )。

To make sure that g (n-1) is evaluated only once in each step, use a let or where statement so that you can refer to a single value - the result of the one call - twice. 要确保在每个步骤中仅对g (n-1)求值一次,请使用letwhere语句,以便您可以两次引用一个值(一次调用的结果)。

g :: Int -> Int
g 4 = 13
g n = let r = g (n-1)
      in r + n `gcd` r

when I tried this code in ideone, it's fine, but in my computer it's not. 当我在ideone中尝试此代码时,这很好,但是在我的计算机中则不是。 Is that haskell version problem? 那是haskell版本的问题吗?

Possibly, although rather an optimisation level parameter problem. 可能是优化级别参数问题。 Haskell's compiler can optimise functions such as yours when it detects that an expression (like g (n-1) ) appears twice, but searching for these is costly and needs to be enabled. Haskell的编译器在检测到表达式(如g (n-1) )出现两次时可以优化您的函数,但是搜索这些函数成本很高并且需要启用。

If you change the definition of g to: 如果将g的定义更改为:

g::Int->Int
g 4=13
g n=x+n `gcd` x
  where x = g (n-1)

then I get acceptable run times even under ghci or runhaskell (as opposed to ghc -O2 .) 那么即使在ghcirunhaskell (相对于ghc -O2 )下,我也可以获得可接受的运行时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM