1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeFamilies #-}
module InitTails (initTailsBenchmarks) where
#if MIN_VERSION_gauge(0,2,0)
import Gauge
#else
import Gauge.Main
#endif
import Data.Sequences as Ss
import Data.MonoTraversable
import Type.Reflection (Typeable, typeRep)
import Control.DeepSeq
import Data.Foldable (foldl')
import Data.Functor ((<&>))
import Data.ByteString (StrictByteString)
import Data.ByteString.Lazy (LazyByteString)
import qualified Data.Text as TS
import qualified Data.Text.Lazy as TL
import Data.Sequence (Seq)
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Storable as VS
initTailsBenchmarks :: Benchmark
initTailsBenchmarks = bgroup "InitTails"
[ bmg @[Char]
, bmg @StrictByteString
, bmg @LazyByteString
, bmg @TS.Text
, bmg @TL.Text
, bmg @(Seq Char)
, bmg @(V.Vector Char)
, bmg @(VU.Vector Char)
, bmg @(VS.Vector Char)
]
bmg :: forall seq.
( TestLabel seq
, NFData seq
, IsSequence seq
, Num (Index seq)
, Enum (Element seq)
) => Benchmark
bmg = bgroup (testLabel @seq) $ bm <$> labelledLengths
where
bm :: (String,[Int]) -> Benchmark
bm (label,lengths) = bgroup label $
[ ("weak", weakConsume)
, ("deep", deepConsume)
] <&> \(wdLabel,consume) -> bench wdLabel
$ nf (map $ consume . initTails @seq)
$ (`Ss.replicate` (toEnum 65)) . fromIntegral <$> lengths
labelledLengths =
[ ("tiny", [0,1,2,5,10])
, ("small", [100,150,200,300])
, ("medium", [1000,1500,2000,2500])
, ("large", [10000,20000,50000])
]
class Typeable a => TestLabel a where
testLabel :: String
testLabel = show $ typeRep @a
instance TestLabel [Char]
instance TestLabel StrictByteString where testLabel = "StrictByteString"
instance TestLabel LazyByteString where testLabel = "LazyByteString"
instance TestLabel TS.Text where testLabel = "StrictText"
instance TestLabel TL.Text where testLabel = "LazyText"
instance TestLabel (Seq Char) where testLabel = "Seq"
instance TestLabel (V.Vector Char) where testLabel = "Vector"
instance TestLabel (VU.Vector Char) where testLabel = "UnboxedVector"
instance TestLabel (VS.Vector Char) where testLabel = "StorableVector"
-- *Consume used to keep memory usage lower
deepConsume :: NFData seq => [(seq,seq)] -> ()
deepConsume = foldl' (\() (is,ts) -> deepseq is $ deepseq ts ()) ()
weakConsume :: [(seq,seq)] -> ()
weakConsume = foldl' (\() (_,_) -> ()) ()
|