fast-digits-0.3.2.0: bench/Bench.hs
{-# LANGUAGE CPP #-}
module Main (main) where
#ifdef MIN_VERSION_digits
import qualified Data.Digits as D (digitsRev)
#endif
import Data.FastDigits (digits, undigits)
import Data.List (foldl')
import Test.Tasty.Bench (Benchmark, Benchmarkable, defaultMain, bench, bgroup, nf)
#ifdef MIN_VERSION_digits
import Test.Tasty.Bench (bcompare)
#endif
#ifdef MIN_VERSION_digits
digitsD :: Int -> Integer -> [Int]
digitsD base n = map fromInteger $ D.digitsRev (toInteger base) n
#endif
intNs :: Int -> Int -> [Int]
intNs from len = [from, step .. maxBound]
where
step = maxBound `div` len
integerN :: Int -> Int -> Integer
integerN from len = undigits (maxBound :: Int) (intNs from len)
benchShort :: (Integer -> [Int]) -> Benchmarkable
benchShort f = flip nf 10000 $
\len -> foldl' (+) 0 $ concatMap (f . toInteger)
[1 :: Int, maxBound `quot` len .. maxBound]
{-# INLINE benchShort #-}
benchMedium :: (Integer -> [Int]) -> Benchmarkable
benchMedium f = flip nf 100 $
\len -> foldl' (+) 0 $ concatMap (f . flip integerN 10) [1 :: Int .. len]
{-# INLINE benchMedium #-}
benchLong :: (Integer -> [Int]) -> Benchmarkable
benchLong f = flip nf 1000 $
\len -> foldl' (+) 0 $ f $ integerN 1 len
{-# INLINE benchLong #-}
benchBase :: ((Integer -> [Int]) -> Benchmarkable) -> String -> Int -> Benchmark
#ifdef MIN_VERSION_digits
benchBase b groupName base = bgroup (show base)
[ bench "FastDigits" (b (digits base))
, bcompare ("$NF == \"FastDigits\" && $(NF-1) == \"" ++ show base ++ "\" && $(NF-2) == \"" ++ groupName ++ "\"")
$ bench "Data.Digits" (b (digitsD base))
]
#else
benchBase b _ base = bench (show base) (b (digits base))
#endif
{-# INLINE benchBase #-}
benchSmth :: String -> ((Integer -> [Int]) -> Benchmarkable) -> Benchmark
benchSmth name b = bgroup name $
[ benchBase b name 2
, benchBase b name 10
, benchBase b name 100000
, benchBase b name 1000000000
]
{-# INLINE benchSmth #-}
main :: IO ()
main = defaultMain
[ benchSmth "short" benchShort
, benchSmth "medium" benchMedium
, benchSmth "long" benchLong
]