-- Benchmark for Oleg Kiselyov's iteratees. You will need:
-- 
-- http://okmij.org/ftp/Haskell/Iteratee/LowLevelIO.hs
-- http://okmij.org/ftp/Haskell/Iteratee/IterateeM.hs
-- http://okmij.org/ftp/Haskell/Iteratee/IterateeMCPS.hs
-- 
-- 
-- ghc --make -O2 benchmark.hs

import Criterion.Main
import Criterion.Config
import qualified IterateeM as M
import qualified IterateeMCPS as CPS
import qualified Control.Monad.Identity as I

config = defaultConfig { cfgPerformGC = ljust True }

enumM :: Monad m => Int -> Int -> M.IterV Int m a -> M.Iteratee Int m a
enumM n = M.enum_pure_nchunk [0..n]

enumCPS :: Monad m => Int -> Int -> CPS.Iteratee Int m a -> m (CPS.Iteratee Int m a)
enumCPS n = CPS.enum_pure_nchunk [0..n]

runM :: (M.IterV el I.Identity () -> M.Iteratee el' I.Identity a) -> a
runM enum = I.runIdentity . M.run $ M.skip_till_eof M.>>== enum

runCPS :: Monad m => (CPS.Iteratee el m () -> CPS.Iteratee el' I.Identity a) -> a
runCPS enum = I.runIdentity . CPS.run $ enum CPS.skip_till_eof

main :: IO ()
main = defaultMainWith config (return ())
	[ bgroup "IterateeM"
		[ bench "100/10" $ whnf runM $ enumM 100 10
		, bench "200/10" $ whnf runM $ enumM 200 10
		, bench "300/10" $ whnf runM $ enumM 300 10
		]
	, bgroup "IterateeCPS"
		[ bench "100/10" $ whnf runCPS $ enumCPS 100 10
		, bench "200/10" $ whnf runCPS $ enumCPS 200 10
		, bench "300/10" $ whnf runCPS $ enumCPS 300 10
		]
	]
