{-# 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' (\() (_,_) -> ()) ()