[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