Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| {-# LANGUAGE CPP #-} | |
| {-# LANGUAGE Trustworthy #-} | |
| {-# LANGUAGE RankNTypes #-} | |
| {-# LANGUAGE DeriveDataTypeable, DeriveGeneric, GADTs, RecordWildCards #-} | |
| {-# OPTIONS_GHC -funbox-strict-fields #-} | |
| -- | | |
| -- Module : Criterion.Types | |
| -- Copyright : (c) 2009-2014 Bryan O'Sullivan | |
| -- | |
| -- License : BSD-style | |
| -- Maintainer : bos@serpentine.com | |
| -- Stability : experimental | |
| -- Portability : GHC | |
| -- | |
| -- Types for benchmarking. | |
| -- | |
| -- The core type is 'Benchmarkable', which admits both pure functions | |
| -- and 'IO' actions. | |
| -- | |
| -- For a pure function of type @a -> b@, the benchmarking harness | |
| -- calls this function repeatedly, each time with a different 'Int64' | |
| -- argument (the number of times to run the function in a loop), and | |
| -- reduces the result the function returns to weak head normal form. | |
| -- | |
| -- For an action of type @IO a@, the benchmarking harness calls the | |
| -- action repeatedly, but does not reduce the result. | |
| module Criterion.Types | |
| ( | |
| -- * Configuration | |
| Config(..) | |
| , Verbosity(..) | |
| -- * Benchmark descriptions | |
| , Benchmarkable(..) | |
| , Benchmark(..) | |
| -- * Measurements | |
| , Measured(..) | |
| , fromInt | |
| , toInt | |
| , fromDouble | |
| , toDouble | |
| , measureAccessors | |
| , measureKeys | |
| , measure | |
| , rescale | |
| -- * Benchmark construction | |
| , env | |
| , envWithCleanup | |
| , perBatchEnv | |
| , perBatchEnvWithCleanup | |
| , perRunEnv | |
| , perRunEnvWithCleanup | |
| , toBenchmarkable | |
| , bench | |
| , bgroup | |
| , addPrefix | |
| , benchNames | |
| -- ** Evaluation control | |
| , nf | |
| , whnf | |
| , nfIO | |
| , whnfIO | |
| , nfAppIO | |
| , whnfAppIO | |
| -- * Result types | |
| , Outliers(..) | |
| , OutlierEffect(..) | |
| , OutlierVariance(..) | |
| , Regression(..) | |
| , KDE(..) | |
| , Report(..) | |
| , SampleAnalysis(..) | |
| , DataRecord(..) | |
| ) where | |
| import Control.DeepSeq (NFData(rnf)) | |
| import Criterion.Measurement.Types | |
| import Data.Aeson (FromJSON(..), ToJSON(..)) | |
| import Data.Binary (Binary(..), putWord8, getWord8) | |
| import Data.Data (Data, Typeable) | |
| import Data.Int (Int64) | |
| import Data.Map (Map) | |
| import GHC.Generics (Generic) | |
| import Prelude () | |
| import Prelude.Compat | |
| import qualified Data.Vector as V | |
| import qualified Data.Vector.Unboxed as U | |
| import qualified Statistics.Types as St | |
| import Statistics.Resampling.Bootstrap () | |
| -- | Control the amount of information displayed. | |
| data Verbosity = Quiet | |
| | Normal | |
| | Verbose | |
| deriving (Eq, Ord, Bounded, Enum, Read, Show, Typeable, Data, | |
| Generic) | |
| -- | Top-level benchmarking configuration. | |
| data Config = Config { | |
| confInterval :: St.CL Double | |
| -- ^ Confidence interval for bootstrap estimation (greater than | |
| -- 0, less than 1). | |
| , timeLimit :: Double | |
| -- ^ Number of seconds to run a single benchmark. (In practice, | |
| -- execution time will very slightly exceed this limit.) | |
| , resamples :: Int | |
| -- ^ Number of resamples to perform when bootstrapping. | |
| , regressions :: [([String], String)] | |
| -- ^ Regressions to perform. | |
| , rawDataFile :: Maybe FilePath | |
| -- ^ File to write binary measurement and analysis data to. If | |
| -- not specified, this will be a temporary file. | |
| , reportFile :: Maybe FilePath | |
| -- ^ File to write report output to, with template expanded. | |
| , csvFile :: Maybe FilePath | |
| -- ^ File to write CSV summary to. | |
| , jsonFile :: Maybe FilePath | |
| -- ^ File to write JSON-formatted results to. | |
| , junitFile :: Maybe FilePath | |
| -- ^ File to write JUnit-compatible XML results to. | |
| , verbosity :: Verbosity | |
| -- ^ Verbosity level to use when running and analysing | |
| -- benchmarks. | |
| , template :: FilePath | |
| -- ^ Template file to use if writing a report. | |
| } deriving (Eq, Read, Show, Typeable, Data, Generic) | |
| -- | Outliers from sample data, calculated using the boxplot | |
| -- technique. | |
| data Outliers = Outliers { | |
| samplesSeen :: !Int64 | |
| , lowSevere :: !Int64 | |
| -- ^ More than 3 times the interquartile range (IQR) below the | |
| -- first quartile. | |
| , lowMild :: !Int64 | |
| -- ^ Between 1.5 and 3 times the IQR below the first quartile. | |
| , highMild :: !Int64 | |
| -- ^ Between 1.5 and 3 times the IQR above the third quartile. | |
| , highSevere :: !Int64 | |
| -- ^ More than 3 times the IQR above the third quartile. | |
| } deriving (Eq, Read, Show, Typeable, Data, Generic) | |
| instance FromJSON Outliers | |
| instance ToJSON Outliers | |
| instance Binary Outliers where | |
| put (Outliers v w x y z) = put v >> put w >> put x >> put y >> put z | |
| get = Outliers <$> get <*> get <*> get <*> get <*> get | |
| instance NFData Outliers | |
| -- | A description of the extent to which outliers in the sample data | |
| -- affect the sample mean and standard deviation. | |
| data OutlierEffect = Unaffected -- ^ Less than 1% effect. | |
| | Slight -- ^ Between 1% and 10%. | |
| | Moderate -- ^ Between 10% and 50%. | |
| | Severe -- ^ Above 50% (i.e. measurements | |
| -- are useless). | |
| deriving (Eq, Ord, Read, Show, Typeable, Data, Generic) | |
| instance FromJSON OutlierEffect | |
| instance ToJSON OutlierEffect | |
| instance Binary OutlierEffect where | |
| put Unaffected = putWord8 0 | |
| put Slight = putWord8 1 | |
| put Moderate = putWord8 2 | |
| put Severe = putWord8 3 | |
| get = do | |
| i <- getWord8 | |
| case i of | |
| 0 -> return Unaffected | |
| 1 -> return Slight | |
| 2 -> return Moderate | |
| 3 -> return Severe | |
| _ -> fail $ "get for OutlierEffect: unexpected " ++ show i | |
| instance NFData OutlierEffect | |
| instance Semigroup Outliers where | |
| (<>) = addOutliers | |
| instance Monoid Outliers where | |
| mempty = Outliers 0 0 0 0 0 | |
| #if !(MIN_VERSION_base(4,11,0)) | |
| mappend = addOutliers | |
| #endif | |
| addOutliers :: Outliers -> Outliers -> Outliers | |
| addOutliers (Outliers s a b c d) (Outliers t w x y z) = | |
| Outliers (s+t) (a+w) (b+x) (c+y) (d+z) | |
| {-# INLINE addOutliers #-} | |
| -- | Analysis of the extent to which outliers in a sample affect its | |
| -- standard deviation (and to some extent, its mean). | |
| data OutlierVariance = OutlierVariance { | |
| ovEffect :: OutlierEffect | |
| -- ^ Qualitative description of effect. | |
| , ovDesc :: String | |
| -- ^ Brief textual description of effect. | |
| , ovFraction :: Double | |
| -- ^ Quantitative description of effect (a fraction between 0 and 1). | |
| } deriving (Eq, Read, Show, Typeable, Data, Generic) | |
| instance FromJSON OutlierVariance | |
| instance ToJSON OutlierVariance | |
| instance Binary OutlierVariance where | |
| put (OutlierVariance x y z) = put x >> put y >> put z | |
| get = OutlierVariance <$> get <*> get <*> get | |
| instance NFData OutlierVariance where | |
| rnf OutlierVariance{..} = rnf ovEffect `seq` rnf ovDesc `seq` rnf ovFraction | |
| -- | Results of a linear regression. | |
| data Regression = Regression { | |
| regResponder :: String | |
| -- ^ Name of the responding variable. | |
| , regCoeffs :: Map String (St.Estimate St.ConfInt Double) | |
| -- ^ Map from name to value of predictor coefficients. | |
| , regRSquare :: St.Estimate St.ConfInt Double | |
| -- ^ R² goodness-of-fit estimate. | |
| } deriving (Eq, Read, Show, Typeable, Generic) | |
| instance FromJSON Regression | |
| instance ToJSON Regression | |
| instance Binary Regression where | |
| put Regression{..} = | |
| put regResponder >> put regCoeffs >> put regRSquare | |
| get = Regression <$> get <*> get <*> get | |
| instance NFData Regression where | |
| rnf Regression{..} = | |
| rnf regResponder `seq` rnf regCoeffs `seq` rnf regRSquare | |
| -- | Result of a bootstrap analysis of a non-parametric sample. | |
| data SampleAnalysis = SampleAnalysis { | |
| anRegress :: [Regression] | |
| -- ^ Estimates calculated via linear regression. | |
| , anMean :: St.Estimate St.ConfInt Double | |
| -- ^ Estimated mean. | |
| , anStdDev :: St.Estimate St.ConfInt Double | |
| -- ^ Estimated standard deviation. | |
| , anOutlierVar :: OutlierVariance | |
| -- ^ Description of the effects of outliers on the estimated | |
| -- variance. | |
| } deriving (Eq, Read, Show, Typeable, Generic) | |
| instance FromJSON SampleAnalysis | |
| instance ToJSON SampleAnalysis | |
| instance Binary SampleAnalysis where | |
| put SampleAnalysis{..} = do | |
| put anRegress; put anMean; put anStdDev; put anOutlierVar | |
| get = SampleAnalysis <$> get <*> get <*> get <*> get | |
| instance NFData SampleAnalysis where | |
| rnf SampleAnalysis{..} = | |
| rnf anRegress `seq` rnf anMean `seq` | |
| rnf anStdDev `seq` rnf anOutlierVar | |
| -- | Data for a KDE chart of performance. | |
| data KDE = KDE { | |
| kdeType :: String | |
| , kdeValues :: U.Vector Double | |
| , kdePDF :: U.Vector Double | |
| } deriving (Eq, Read, Show, Typeable, Data, Generic) | |
| instance FromJSON KDE | |
| instance ToJSON KDE | |
| instance Binary KDE where | |
| put KDE{..} = put kdeType >> put kdeValues >> put kdePDF | |
| get = KDE <$> get <*> get <*> get | |
| instance NFData KDE where | |
| rnf KDE{..} = rnf kdeType `seq` rnf kdeValues `seq` rnf kdePDF | |
| -- | Report of a sample analysis. | |
| data Report = Report { | |
| reportNumber :: Int | |
| -- ^ A simple index indicating that this is the /n/th report. | |
| , reportName :: String | |
| -- ^ The name of this report. | |
| , reportKeys :: [String] | |
| -- ^ See 'measureKeys'. | |
| , reportMeasured :: V.Vector Measured | |
| -- ^ Raw measurements. | |
| , reportAnalysis :: SampleAnalysis | |
| -- ^ Report analysis. | |
| , reportOutliers :: Outliers | |
| -- ^ Analysis of outliers. | |
| , reportKDEs :: [KDE] | |
| -- ^ Data for a KDE of times. | |
| } deriving (Eq, Read, Show, Typeable, Generic) | |
| instance FromJSON Report | |
| instance ToJSON Report | |
| instance Binary Report where | |
| put Report{..} = | |
| put reportNumber >> put reportName >> put reportKeys >> | |
| put reportMeasured >> put reportAnalysis >> put reportOutliers >> | |
| put reportKDEs | |
| get = Report <$> get <*> get <*> get <*> get <*> get <*> get <*> get | |
| instance NFData Report where | |
| rnf Report{..} = | |
| rnf reportNumber `seq` rnf reportName `seq` rnf reportKeys `seq` | |
| rnf reportMeasured `seq` rnf reportAnalysis `seq` rnf reportOutliers `seq` | |
| rnf reportKDEs | |
| data DataRecord = Measurement Int String (V.Vector Measured) | |
| | Analysed Report | |
| deriving (Eq, Read, Show, Typeable, Generic) | |
| instance Binary DataRecord where | |
| put (Measurement i n v) = putWord8 0 >> put i >> put n >> put v | |
| put (Analysed r) = putWord8 1 >> put r | |
| get = do | |
| w <- getWord8 | |
| case w of | |
| 0 -> Measurement <$> get <*> get <*> get | |
| 1 -> Analysed <$> get | |
| _ -> error ("bad tag " ++ show w) | |
| instance NFData DataRecord where | |
| rnf (Measurement i n v) = rnf i `seq` rnf n `seq` rnf v | |
| rnf (Analysed r) = rnf r | |
| instance FromJSON DataRecord | |
| instance ToJSON DataRecord |