Skip to content

Instantly share code, notes, and snippets.

@snoyberg
Created June 3, 2018 22:28
Show Gist options
  • Save snoyberg/66b7448331207e26c76e9619e4a53255 to your computer and use it in GitHub Desktop.
Save snoyberg/66b7448331207e26c76e9619e4a53255 to your computer and use it in GitHub Desktop.
Benchmarking implementations of foldMapM
#!/usr/bin/env stack
-- stack --resolver lts-11.10 script --optimize
import Gauge
import qualified Data.Vector as V
import qualified Data.Foldable as F
import Data.Functor.Identity (runIdentity)
import Data.Monoid (Sum (..))
import Data.Semigroup (Semigroup (..))
import Control.Applicative (liftA2)
nums :: V.Vector Int
nums = V.enumFromTo 1 1000000
main :: IO ()
main = defaultMain
[ bench "sum" $ whnf sum nums
, bench "F.foldl'" $ whnf (F.foldl' (+) 0) nums
, bench "V.foldl'" $ whnf (V.foldl' (+) 0) nums
, bench "F.foldlM Identity" $ whnf (runIdentity . F.foldlM (\x y -> return $! x + y) 0) nums
, bench "F.foldlM IO" $ whnfIO $ F.foldlM (\x y -> return $! x + y) 0 nums
, bench "F.foldMap Sum" $ whnf (getSum . F.foldMap Sum) nums
, bench "foldMapM 1 Identity" $ whnf (getSum . runIdentity . foldMapM1 (return . Sum)) nums
, bench "foldMapM 1 IO" $ whnfIO $ fmap getSum $ foldMapM1 (return . Sum) nums
, bench "foldMapM 2 Identity" $ whnf (getSum . runIdentity . foldMapM2 (return . Sum)) nums
, bench "foldMapM 2 IO" $ whnfIO $ fmap getSum $ foldMapM2 (return . Sum) nums
]
foldMapM1 :: (Foldable t, Applicative m, Monoid w) => (a -> m w) -> t a -> m w
foldMapM1 f = runFMHelper . foldMap (FMHelper . f)
newtype FMHelper f a = FMHelper { runFMHelper :: f a }
instance (Applicative f, Semigroup a) => Semigroup (FMHelper f a) where
FMHelper x <> FMHelper y = FMHelper (liftA2 (<>) x y)
instance (Applicative f, Monoid a) => Monoid (FMHelper f a) where
mempty = FMHelper (pure mempty)
mappend (FMHelper x) (FMHelper y) = FMHelper (liftA2 mappend x y)
foldMapM2 :: (Foldable t, Monad m, Monoid w) => (a -> m w) -> t a -> m w
foldMapM2 f = F.foldlM
(\acc a -> do
w <- f a
return $! mappend acc w)
mempty
benchmarking sum ...
benchmarked sum
time 5.993 ms (5.522 ms .. 6.748 ms)
0.962 R² (0.942 R² .. 0.994 R²)
mean 4.589 ms (4.382 ms .. 4.835 ms)
std dev 696.5 us (559.9 us .. 1.007 ms)
variance introduced by outliers: 74% (severely inflated)
benchmarking F.foldl' ...
benchmarked F.foldl'
time 4.995 ms (4.857 ms .. 5.094 ms)
0.997 R² (0.991 R² .. 0.999 R²)
mean 5.145 ms (5.073 ms .. 5.419 ms)
std dev 369.9 us (99.47 us .. 811.9 us)
variance introduced by outliers: 41% (moderately inflated)
benchmarking V.foldl' ...
benchmarked V.foldl'
time 5.079 ms (5.038 ms .. 5.114 ms)
1.000 R² (0.999 R² .. 1.000 R²)
mean 5.055 ms (5.040 ms .. 5.079 ms)
std dev 55.71 us (41.14 us .. 84.08 us)
benchmarking F.foldlM Identity ...
benchmarked F.foldlM Identity
time 5.172 ms (5.086 ms .. 5.266 ms)
0.999 R² (0.998 R² .. 1.000 R²)
mean 5.082 ms (5.062 ms .. 5.111 ms)
std dev 72.57 us (51.40 us .. 98.69 us)
benchmarking F.foldlM IO ...
benchmarked F.foldlM IO
time 6.996 ms (5.861 ms .. 9.321 ms)
0.787 R² (0.666 R² .. 0.996 R²)
mean 6.189 ms (5.944 ms .. 7.215 ms)
std dev 1.109 ms (208.9 us .. 2.407 ms)
variance introduced by outliers: 75% (severely inflated)
benchmarking F.foldMap Sum ...
benchmarked F.foldMap Sum
time 25.43 ms (25.02 ms .. 25.88 ms)
0.999 R² (0.999 R² .. 1.000 R²)
mean 24.83 ms (24.34 ms .. 25.20 ms)
std dev 944.8 us (532.6 us .. 1.719 ms)
variance introduced by outliers: 10% (moderately inflated)
benchmarking foldMapM 1 Identity ...
benchmarked foldMapM 1 Identity
time 25.48 ms (25.05 ms .. 26.12 ms)
0.997 R² (0.992 R² .. 0.999 R²)
mean 24.86 ms (24.37 ms .. 25.31 ms)
std dev 1.022 ms (655.2 us .. 1.649 ms)
variance introduced by outliers: 10% (moderately inflated)
benchmarking foldMapM 1 IO ... took 12.92 s, total 56 iterations
benchmarked foldMapM 1 IO
time 227.4 ms (225.0 ms .. 229.1 ms)
1.000 R² (1.000 R² .. 1.000 R²)
mean 229.4 ms (228.3 ms .. 230.8 ms)
std dev 2.091 ms (1.338 ms .. 2.858 ms)
benchmarking foldMapM 2 Identity ...
benchmarked foldMapM 2 Identity
time 5.129 ms (5.073 ms .. 5.202 ms)
0.999 R² (0.999 R² .. 1.000 R²)
mean 5.130 ms (5.114 ms .. 5.152 ms)
std dev 58.04 us (44.83 us .. 77.71 us)
benchmarking foldMapM 2 IO ...
benchmarked foldMapM 2 IO
time 14.52 ms (14.48 ms .. 14.59 ms)
1.000 R² (0.999 R² .. 1.000 R²)
mean 14.51 ms (14.48 ms .. 14.58 ms)
std dev 93.96 us (30.93 us .. 178.8 us)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment