{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Data.GenValidity.Criterion
( genValidityBench,
genUncheckedBench,
genValidBench,
genBenchSizes,
genBench,
)
where
import Control.DeepSeq
import Criterion
import Data.GenValidity
import Data.Typeable
import Test.QuickCheck
genValidityBench ::
forall a.
(Typeable a, NFData a, GenUnchecked a, GenValid a) =>
Benchmark
genValidityBench =
bgroup (unwords ["GenValidity", nameOf @a]) [genValidBench @a, genUncheckedBench @a]
genUncheckedBench ::
forall a.
(Typeable a, NFData a, GenUnchecked a) =>
Benchmark
genUncheckedBench = genBenchSizes (unwords ["genUnchecked", nameOf @a]) (genUnchecked @a)
genValidBench ::
forall a.
(Typeable a, NFData a, GenValid a) =>
Benchmark
genValidBench = genBenchSizes (unwords ["genValid", nameOf @a]) (genValid @a)
genBenchSizes :: NFData a => String -> Gen a -> Benchmark
genBenchSizes name gen =
bgroup name $
let bi i = genBench ("size " <> show i) (resize i gen)
in [bi 8, bi 16, bi 32, bi 64]
genBench :: NFData a => String -> Gen a -> Benchmark
genBench name gen =
bench name $ nfIO $ generate gen
nameOf ::
forall a.
Typeable a =>
String
nameOf =
let s = show $ typeRep (Proxy @a)
in if ' ' `elem` s
then "(" ++ s ++ ")"
else s