foldl-1.4.10: bench/Foldl.hs
{-# LANGUAGE BangPatterns #-}
module Main (main) where
import Control.Foldl hiding (map)
import Criterion.Main
import qualified Data.List
import Prelude hiding (length, sum)
import qualified Prelude
import qualified Data.Foldable as Foldable
main :: IO ()
main = defaultMain
[ env (return [1..10000 :: Int]) $ \ns ->
bgroup "[1..10000 :: Int]"
[ bgroup "sum" $ map ($ ns)
[ bench "fold sum" .
whnf (fold sum)
, bench "foldM (generalize sum)" .
whnfIO . foldM (generalize sum)
, bench "Prelude.sum" .
whnf Prelude.sum
, bench "Data.List.foldl' (+) 0" .
whnf (Data.List.foldl' (+) 0)
]
, bgroup "filtered" $ map ($ ns)
[ bench "fold (handles (filtered even) list)" .
nf (fold (handles (filtered even) list))
, bench "foldM (handlesM (filtered even) (generalize list))" .
nfIO . foldM (handlesM (filtered even) (generalize list))
, bench "filter even" .
nf (filter even)
]
, bgroup "length" $ map ($ ns)
[ bench "fold length" .
whnf (fold length)
, bench "foldM (generalize length)" .
whnfIO . foldM (generalize length)
, bench "Prelude.length" .
whnf Prelude.length
]
, bgroup "sumAndLength" $ map ($ ns)
[ bench "naive sumAndLength" .
nf sumAndLength
, bench "foldl' sumAndLength" .
nf sumAndLength'
, bench "strict pair sumAndLength" .
nf sumAndLength_Pair
, bench "foldl sumAndLength" .
nf sumAndLength_foldl
]
]
]
sumAndLength :: Num a => [a] -> (a, Int)
sumAndLength xs = (Prelude.sum xs, Prelude.length xs)
sumAndLength' :: Num a => [a] -> (a, Int)
sumAndLength' xs = Foldable.foldl' step (0, 0) xs
where
step (x, y) n = (x + n, y + 1)
data Pair a b = Pair !a !b
sumAndLength_Pair :: Num a => [a] -> (a, Int)
sumAndLength_Pair xs = done (Foldable.foldl' step (Pair 0 0) xs)
where
step (Pair x y) n = Pair (x + n) (y + 1)
done (Pair x y) = (x, y)
sumAndLength_foldl :: Num a => [a] -> (a, Int)
sumAndLength_foldl = fold ((,) <$> sum <*> length)