[Haskell-beginners] Performance of Idiomatic lazy Haskell

Stephen Tetley stephen.tetley at gmail.com
Sun Jan 31 13:21:10 EST 2010


Hello Daniel

I can get close with a tail recursive + accumulator monoidal unfoldr
and strict triple for the state (leibniz4).

But it does seem to be loosing the point of the initial exercise "to
be idiomatic", also the answers are divergent too...


Best wishes

Stephen

------
Leibniz4 - monodial unfoldr strict triple
------

$ ./Leibniz4 +RTS -sstderr -RTS
d:\coding\haskell\cafe\Leibniz4.exe +RTS -sstderr
EPS:
PI mit EPS 1.0e-8 = 3.1415926526069526
          24,424 bytes allocated in the heap
             892 bytes copied during GC
           3,068 bytes maximum residency (1 sample(s))
          13,316 bytes maximum slop
               1 MB total memory in use (0 MB lost due to fragmentation)

  Generation 0:     0 collections,     0 parallel,  0.00s,  0.00s elapsed
  Generation 1:     1 collections,     0 parallel,  0.00s,  0.00s elapsed

  INIT  time    0.03s  (  0.00s elapsed)
  MUT   time    4.34s  (  4.45s elapsed)
  GC    time    0.00s  (  0.00s elapsed)
  EXIT  time    0.00s  (  0.00s elapsed)
  Total time    4.38s  (  4.45s elapsed)

  %GC time       0.0%  (0.0% elapsed)

  Alloc rate    5,582 bytes per MUT second

  Productivity  99.3% of total user, 97.5% of total elapsed

------
Leibniz1 - stream fusion
------

$ ./Leibniz1 +RTS -sstderr -RTS
d:\coding\haskell\cafe\Leibniz1.exe +RTS -sstderr
EPS:
PI mit EPS 1.0e-8 = 3.1415926445727678
          24,404 bytes allocated in the heap
             892 bytes copied during GC
           3,068 bytes maximum residency (1 sample(s))
          13,316 bytes maximum slop
               1 MB total memory in use (0 MB lost due to fragmentation)

  Generation 0:     0 collections,     0 parallel,  0.00s,  0.00s elapsed
  Generation 1:     1 collections,     0 parallel,  0.00s,  0.00s elapsed

  INIT  time    0.02s  (  0.00s elapsed)
  MUT   time    4.61s  (  4.63s elapsed)
  GC    time    0.00s  (  0.00s elapsed)
  EXIT  time    0.00s  (  0.00s elapsed)
  Total time    4.63s  (  4.63s elapsed)

  %GC time       0.0%  (0.0% elapsed)

  Alloc rate    5,276 bytes per MUT second

  Productivity  99.7% of total user, 99.7% of total elapsed


----------


module Main (main) where

import Data.Monoid


data Maybe2 a st = Nothing2 | Just2 a !st
  deriving (Eq,Show)

dummy_eps :: Double
dummy_eps = 0.00000001

main :: IO ()
main = do
    putStrLn "EPS: "
    eps <- return dummy_eps
    let mx = floor (4/eps)
        !k = (mx+1) `quot` 2
    putStrLn $ "PI mit EPS " ++ (show eps) ++ " = " ++ show (leibniz k)

leibniz :: Integer -> Double
leibniz n = (4 *) $ getSum $ step (fromIntegral n)

data Trip = T3 !Int !Bool !Double

step :: Int -> Sum Double
step times = unfoldrMon phi (T3 0 True 1) where
   phi :: Trip -> Maybe2 (Sum Double) Trip
   phi (T3 i _   _) | i == times  = Nothing2
   phi (T3 i sig d) | sig         = Just2 (Sum (1/d)) (T3 (i+1) False (d+2))
                    | otherwise   = Just2 (Sum (negate (1/d))) (T3
(i+1) True (d+2))



unfoldrMon      :: Monoid a => (b -> Maybe2 a b) -> b -> a
unfoldrMon f b0  = step b0 mempty where
   step b acc = case f b of
              Nothing2       -> acc
              Just2 a new_b  -> step new_b  (a `mappend` acc)


More information about the Beginners mailing list