module Cryptol.Utils.Benchmark
( BenchmarkStats (..)
, benchmark
, secs
) where
import Criterion.Measurement (runBenchmark, secs, threshold)
import Criterion.Measurement.Types
import Data.Int
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as U
data BenchmarkStats = BenchmarkStats
{ BenchmarkStats -> Double
benchAvgTime :: !Double
, BenchmarkStats -> Double
benchAvgCpuTime :: !Double
, BenchmarkStats -> Int64
benchAvgCycles :: !Int64
} deriving Int -> BenchmarkStats -> ShowS
[BenchmarkStats] -> ShowS
BenchmarkStats -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BenchmarkStats] -> ShowS
$cshowList :: [BenchmarkStats] -> ShowS
show :: BenchmarkStats -> String
$cshow :: BenchmarkStats -> String
showsPrec :: Int -> BenchmarkStats -> ShowS
$cshowsPrec :: Int -> BenchmarkStats -> ShowS
Show
benchmark :: Double -> (a -> IO b) -> a -> IO BenchmarkStats
benchmark :: forall a b. Double -> (a -> IO b) -> a -> IO BenchmarkStats
benchmark Double
period a -> IO b
f a
x = do
(Vector Measured
meas, Double
_) <- Benchmarkable -> Double -> IO (Vector Measured, Double)
runBenchmark (forall a b. (a -> IO b) -> a -> Benchmarkable
whnfAppIO a -> IO b
f a
x) Double
period
let meas' :: Vector Measured
meas' = Measured -> Measured
rescale forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. (a -> Bool) -> Vector a -> Vector a
V.filter ((forall a. Ord a => a -> a -> Bool
>= Double
threshold) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Measured -> Double
measTime) Vector Measured
meas
len :: Int
len = forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector Measured
meas'
sumMeasure :: (Measured -> a) -> a
sumMeasure Measured -> a
sel = forall a. (Unbox a, Num a) => Vector a -> a
U.sum forall a b. (a -> b) -> a -> b
$ forall a. Unbox a => (Measured -> a) -> Vector Measured -> Vector a
measure Measured -> a
sel Vector Measured
meas'
forall (f :: * -> *) a. Applicative f => a -> f a
pure BenchmarkStats
{ benchAvgTime :: Double
benchAvgTime = forall {a}. (Unbox a, Num a) => (Measured -> a) -> a
sumMeasure Measured -> Double
measTime forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
, benchAvgCpuTime :: Double
benchAvgCpuTime = forall {a}. (Unbox a, Num a) => (Measured -> a) -> a
sumMeasure Measured -> Double
measCpuTime forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
, benchAvgCycles :: Int64
benchAvgCycles = forall {a}. (Unbox a, Num a) => (Measured -> a) -> a
sumMeasure Measured -> Int64
measCycles forall a. Integral a => a -> a -> a
`div` forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len }