large-hashable-0.1.1.0: benchmark/Data/LargeHashable/Benchmarks/Main.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Data.LargeHashable.Benchmarks.Main (main) where
import Control.DeepSeq
import Criterion
import Criterion.Main
import Data.SafeCopy
import Data.Serialize.Put
import GHC.Generics
import qualified Data.Bytes.Serial as S
import qualified Data.LargeHashable as LH
import qualified Data.LargeHashable.Class as LH
import qualified Data.LargeHashable.Intern as LH
import qualified Data.LargeHashable.Benchmarks.CryptoHash as CH
import qualified Data.LargeHashable.Benchmarks.Serial as Serial
import qualified Data.LargeHashable.Benchmarks.Text as TextBench
import qualified Data.Text as T
data Patient
= Patient
{ p_firstName :: !T.Text
, p_lastName :: !T.Text
, p_note :: !T.Text
, p_age :: !Int
}
deriving (Eq, Show, NFData, Generic)
$(deriveSafeCopy 0 'base ''Patient)
$(LH.deriveLargeHashable ''Patient)
instance S.Serial Patient
instance CH.LargeHashable Patient where
hashUpdate ctx0 p =
let !ctx1 = CH.hashUpdate ctx0 (p_firstName p)
!ctx2 = CH.hashUpdate ctx1 (p_lastName p)
!ctx3 = CH.hashUpdate ctx2 (p_note p)
!ctx4 = CH.hashUpdate ctx3 (p_age p)
in ctx4
updateHashPatient :: Patient -> LH.LH ()
updateHashPatient p =
{-# SCC "updateHash/LargHashable" #-}
do {-# SCC "updateHash/firstName" #-} LH.updateHash (p_firstName p)
{-# SCC "updateHash/lastName" #-} LH.updateHash (p_lastName p)
{-# SCC "updateHash/note" #-} LH.updateHash (p_note p)
{-# SCC "updateHash/age" #-} LH.updateHash (p_age p)
mkPatList :: Int -> [Patient]
mkPatList n =
let l = map mkPat [1..n]
in l `deepseq` l
where
mkPat i =
Patient
{ p_firstName = "Stefan"
, p_lastName = "Wehr"
, p_note = "Dies ist ein bißchen mehr Text, aber auch nicht richtig lang"
, p_age = i
}
_NUM_ :: Int
_NUM_ = 100000
patList :: [Patient]
patList = mkPatList _NUM_
main :: IO ()
main =
defaultMain
[ env (return patList) $ \l ->
bgroup "patList"
[ bench "safecopy" $ whnf (CH.hashMd5 . runPut . safePut) l
, bench "cryptohash" $ whnf CH.hashMd5 l
, bench "large-hashable (Manual)" $ whnf (LH.runLH LH.md5HashAlgorithm . LH.updateHashList updateHashPatient) l
, bench "large-hashable (TH)" $ whnf (LH.largeHash LH.md5HashAlgorithm) l
, bench "large-hashable (Generic)" $ whnf (LH.runLH LH.md5HashAlgorithm . LH.genericUpdateHash) l
, bench "large-hashable-serial (TH)" $ whnf (Serial.serialLargeHash LH.md5HashAlgorithm) l
]
, env TextBench.setup $ \ ~(text, string) ->
bgroup "text"
[ bench "text-utf8" $ whnf TextBench.benchTextUtf8 text
, bench "text-utf16" $ whnf TextBench.benchTextUtf16 text
, bench "text-unicode" $ whnf TextBench.benchTextUnicode text
, bench "string" $ whnf TextBench.benchTextString string
]
]