[Haskell-beginners] Performance of Idiomatic lazy Haskell

Markus Böhm markus.boehm at googlemail.com
Sun Jan 31 05:14:36 EST 2010


As a beginner fascinated about Haskell's lazy, idiomatic style I tried
a small example:
Calculate a numerical approximation of PI based on the Leibniz formula.

Variant 1: My lazy, idiomatic approach (as I understand it so far).
It takes on my machine with eps = 0.00000001 approx. 25 sec.

import Data.List

main :: IO ()
main = do putStrLn "EPS: "
          eps <- readLn :: IO Double
          let pi14 = calcpi14 eps
          putStrLn $ "PI mit EPS "++(show eps)++" = "++ show(4*pi14)

calcpi14:: Double->Double
calcpi14 eps = foldl' (+) 0 $ takeWhile (\x -> 4 * abs x > eps) ev
     where e = map (\x->1.0/x) [1.0,3.0..]
           ev = zipWith (*) e $ cycle [1.0,-1.0]


Variant 2: My "C-style" approach achieving state via additonal
function parameters.
It takes on my machine with eps = 0.00000001 approx. 5 sec.

import Data.List

main :: IO ()
main = do putStrLn "EPS: "
          eps <- readLn :: IO Double
          let pi14 = pisum 1 3 False eps
          putStrLn $ "PI mit EPS "++(show eps)++" = "++ show(4*pi14)

pisum s i _     eps | 4/i < eps = s
pisum s i True  eps =
    let h = s + 1/i
    in h `seq` pisum h (i+2) False eps
pisum s i False eps =
    let h = s - 1/i
    in h `seq` pisum h (i+2) True eps

I'd like to do idiomatic, lazy Haskell w/o such a performance penalty?
How can I learn/achive that?


-- Markus


More information about the Beginners mailing list