2016-06-01 03:24:49 +03:00
{- # LANGUAGE DeriveAnyClass, DeriveGeneric, FlexibleInstances, StandaloneDeriving # -}
2016-06-06 22:32:16 +03:00
{- # OPTIONS_GHC - fno - warn - orphans # -}
2016-05-31 16:23:43 +03:00
module Main where
2016-05-31 16:27:00 +03:00
import Criterion.Main
2016-06-06 22:32:38 +03:00
import Data.Function
2016-06-07 00:17:19 +03:00
import Data.List ( genericLength )
2016-05-31 17:37:34 +03:00
import Data.String
2016-06-06 22:32:16 +03:00
import Patch
2016-05-31 16:27:00 +03:00
import Prologue
2016-06-06 22:32:38 +03:00
import SES
2016-06-01 03:24:49 +03:00
import Test.QuickCheck hiding ( Fixed )
2016-05-31 16:27:00 +03:00
main :: IO ()
2016-05-31 17:53:23 +03:00
main = do
2016-06-06 22:32:38 +03:00
benchmarks <- sequenceA [ generativeBenchmark " ses " 10 ( uncurry ( ( * ) ` on ` length ) ) ( nf ( uncurry benchmarkSES ) ) ]
2016-05-31 17:53:23 +03:00
defaultMain benchmarks
2016-05-31 17:37:34 +03:00
2016-06-07 00:16:52 +03:00
benchmarkSES :: [ String ] -> [ String ] -> [ Either String ( Patch String ) ]
2016-06-06 22:32:38 +03:00
benchmarkSES as bs = ses compare cost as bs
where compare a b = if a == b then Just ( Left a ) else Nothing
2016-06-07 00:17:19 +03:00
cost = either ( const 0 ) ( sum . fmap genericLength )
2016-06-06 22:32:38 +03:00
2016-06-06 22:32:16 +03:00
instance NFData a => NFData ( Patch a )
2016-05-31 18:47:56 +03:00
-- | Defines a named group of n benchmarks over inputs generated by an `Arbitrary` instance.
-- |
-- | The inputs’ sizes at each iteration are measured by a metric function, which gives the name of the benchmark. This makes it convenient to correlate a benchmark of some function over lists with e.g. input `length`.
2016-05-31 23:01:36 +03:00
generativeBenchmark :: ( Arbitrary a , Show m , Ord m ) => String -> Int -> ( a -> m ) -> ( a -> Benchmarkable ) -> IO Benchmark
2016-06-07 00:15:51 +03:00
generativeBenchmark name n metric benchmark = generativeBenchmarkWith name n arbitrary metric benchmark
generativeBenchmarkWith :: ( Show m , Ord m ) => String -> Int -> Gen a -> ( a -> m ) -> ( a -> Benchmarkable ) -> IO Benchmark
generativeBenchmarkWith name n generator metric benchmark = do
2016-05-31 18:45:17 +03:00
benchmarks <- traverse measure ( replicate n defaultSize )
2016-05-31 23:01:36 +03:00
pure $! bgroup name ( snd <$> ( sortOn fst benchmarks ) )
2016-05-31 17:37:34 +03:00
where measure n = do
2016-06-07 00:15:51 +03:00
input <- generate ( resize n generator )
2016-05-31 17:37:34 +03:00
let measurement = metric input
2016-05-31 23:01:36 +03:00
pure $! ( measurement , bench ( show measurement ) ( benchmark input ) )
2016-05-31 18:42:51 +03:00
defaultSize = 100