import Control.DeepSeq (NFData, deepseq, force)
import Control.Exception (evaluate)
import Data.Ix (Ix(..))
import Test.Tasty.Bench
(Benchmark, bgroup, bench, defaultMain, env, nf)
import qualified Unicode.Char.General as G
import qualified Unicode.Char.General.Scripts as S
main :: IO ()
main = defaultMain
[ bgroup "Unicode.Char.General.Script"
[ bgroup "script"
[ benchChars "unicode-data" (show . S.script)
]
, bgroup "scriptDefinition"
[ benchNF "unicode-data" (show . S.scriptDefinition)
]
, bgroup "scriptExtensions"
[ benchChars "unicode-data" (show . S.scriptExtensions)
]
]
]
where
benchChars :: forall a. (NFData a) => String -> (Char -> a) -> Benchmark
benchChars t f =
-- Avoid side-effects with garbage collection (see tasty-bench doc)
env
(evaluate (force chars)) -- initialize
(bench t . nf (foldString f)) -- benchmark
where
-- Filter out: Surrogates, Private Use Areas and unsassigned code points
chars = filter isValid [minBound..maxBound]
isValid c = G.generalCategory c < G.Surrogate
foldString :: forall a. (NFData a) => (Char -> a) -> String -> ()
foldString f = foldr (deepseq . f) ()
benchNF
:: forall a b. (Bounded a, Ix a, NFData b)
=> String
-> (a -> b)
-> Benchmark
benchNF t f = bench t (nf (fold_ f) (minBound, maxBound))
fold_
:: forall a b. (Ix a, NFData b)
=> (a -> b)
-> (a, a)
-> ()
fold_ f = foldr (deepseq . f) () . range