circular-0.2.0: bench/Bench.hs
-- |
-- Module : Main
-- Description : Benchmark circular stacks
-- Copyright : (c) Dominik Schrempf, 2020
-- License : GPL-3.0-or-later
--
-- Maintainer : dominik.schrempf@gmail.com
-- Stability : unstable
-- Portability : portable
--
-- Creation date: Sat Jun 20 21:12:38 2020.
module Main
( main,
)
where
import Control.Monad.ST
import Criterion.Main
import Data.Foldable
import qualified Data.Stack.Circular as C
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as U
-- When using foldl or foldl', list is much slower than cstack.
listFoldL :: Int -> Int
listFoldL l = sum $ take 1000 $ foldl (flip (:)) [] [0 .. l]
cstackV :: Int -> Int
cstackV l = runST $ do
c <- C.replicate 1000 0 :: ST s (C.MStack V.Vector s Int)
c' <- foldlM (flip C.push) c [0 .. l]
C.sum c'
cstackU :: Int -> Int
cstackU l = runST $ do
c <- C.replicate 1000 0 :: ST s (C.MStack U.Vector s Int)
c' <- foldlM (flip C.push) c [0 .. l]
C.sum c'
-- When using foldr, cstack is slower by far. This is because list are lazy.
main :: IO ()
main = do
let l = 1000000 :: Int
print $ listFoldL l
print $ cstackU l
defaultMain
[ bench "list, foldl" $ whnf listFoldL l,
bench "cstack, foldl" $ whnf cstackV l,
bench "cstack unboxed, foldl" $ whnf cstackU l
]
-- benchmarking list, foldl
-- time 196.5 ms (169.7 ms .. 219.9 ms)
-- 0.983 R² (0.933 R² .. 1.000 R²)
-- mean 213.9 ms (197.8 ms .. 238.8 ms)
-- std dev 25.51 ms (10.44 ms .. 37.57 ms)
-- variance introduced by outliers: 31% (moderately inflated)
-- benchmarking cstack, foldl
-- time 18.65 ms (18.11 ms .. 19.24 ms)
-- 0.993 R² (0.983 R² .. 0.999 R²)
-- mean 18.46 ms (18.13 ms .. 18.99 ms)
-- std dev 979.7 μs (565.1 μs .. 1.446 ms)
-- variance introduced by outliers: 21% (moderately inflated)
-- benchmarking cstack unboxed, foldl
-- time 13.97 ms (13.91 ms .. 14.05 ms)
-- 1.000 R² (1.000 R² .. 1.000 R²)
-- mean 13.98 ms (13.95 ms .. 14.02 ms)
-- std dev 86.51 μs (61.56 μs .. 120.9 μs)