criterion 1.2.6.0 → 1.3.0.0
raw patch · 14 files changed
+103/−107 lines, 14 filesdep ~basedep ~base-compatPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, base-compat
API changes (from Hackage documentation)
- Criterion.Measurement: applyGCStats :: Maybe GCStats -> Maybe GCStats -> Measured -> Measured
- Criterion.Measurement: getGCStats :: IO (Maybe GCStats)
- Criterion.Types: [forceGC] :: Config -> Bool
- Criterion.Measurement: runBenchmarkable :: Benchmarkable -> Int64 -> (a -> a -> a) -> (IO () -> IO a) -> IO a
+ Criterion.Measurement: runBenchmarkable :: Benchmarkable -> Int64 -> (a -> a -> a) -> (Int64 -> IO () -> IO a) -> IO a
- Criterion.Types: Config :: CL Double -> Bool -> Double -> Int -> [([String], String)] -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Verbosity -> FilePath -> Config
+ Criterion.Types: Config :: CL Double -> Double -> Int -> [([String], String)] -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Maybe FilePath -> Verbosity -> FilePath -> Config
Files
- Criterion/Analysis.hs +2/−4
- Criterion/IO.hs +4/−4
- Criterion/Main/Options.hs +4/−9
- Criterion/Measurement.hs +17/−64
- Criterion/Monad/Internal.hs +2/−4
- Criterion/Types.hs +3/−11
- README.markdown +1/−1
- app/Options.hs +4/−2
- changelog.md +33/−0
- criterion.cabal +7/−3
- examples/Maps.hs +11/−1
- examples/criterion-examples.cabal +11/−2
- tests/Cleanup.hs +3/−2
- tests/Sanity.hs +1/−0
Criterion/Analysis.hs view
@@ -30,9 +30,6 @@ , regress ) where --- Temporary: to support pre-AMP GHC 7.8.4:-import Data.Monoid - import Control.Arrow (second) import Control.Monad (unless, when) import Control.Monad.Reader (ask)@@ -44,6 +41,8 @@ import Criterion.Types import Data.Int (Int64) import Data.Maybe (fromJust)+import Prelude ()+import Prelude.Compat import Statistics.Function (sort) import Statistics.Quantile (weightedAvg) import Statistics.Regression (bootstrapRegress, olsRegress)@@ -59,7 +58,6 @@ import qualified Data.Vector.Unboxed as U import qualified Statistics.Resampling.Bootstrap as B import qualified Statistics.Types as B-import Prelude -- | Classify outliers in a data set, using the boxplot technique. classifyOutliers :: Sample -> Outliers
Criterion/IO.hs view
@@ -52,7 +52,7 @@ -- | The magic string we expect to start off the header. headerRoot :: String-headerRoot = "criterio"+headerRoot = "criterion" -- | The current version of criterion, encoded into a string that is -- used in files.@@ -118,12 +118,12 @@ Right (tg,vers,_) | tg == headerRoot && vers == critVersion -> return res | otherwise ->- do hPutStrLn stderr $ "Warning, readJSONReports: mismatched header, expected " + do hPutStrLn stderr $ "Warning, readJSONReports: mismatched header, expected " ++ show (headerRoot,critVersion) ++ " received " ++ show (tg,vers)- return res + return res -- | Write a list of reports to a JSON file. Includes a header, which--- includes the current Criterion version number. This should be +-- includes the current Criterion version number. This should be -- the inverse of `readJSONReports`. writeJSONReports :: FilePath -> [Report] -> IO () writeJSONReports fn rs =
Criterion/Main/Options.hs view
@@ -1,8 +1,5 @@ {-# LANGUAGE DeriveDataTypeable, DeriveGeneric, RecordWildCards #-} --- Disable deprecation warnings for now until we remove forceGC for good-{-# OPTIONS_GHC -fno-warn-deprecations #-}- -- | -- Module : Criterion.Main.Options -- Copyright : (c) 2014 Bryan O'Sullivan@@ -25,8 +22,8 @@ , versionInfo ) where --- Temporary: to support pre-AMP GHC 7.8.4:-import Data.Monoid+-- Temporary: to support pre-SMP+import Data.Semigroup ((<>)) import Control.Monad (when) import Criterion.Analysis (validateAccessors)@@ -43,10 +40,11 @@ import Options.Applicative.Help.Pretty ((.$.)) import Options.Applicative.Types import Paths_criterion (version)+import Prelude ()+import Prelude.Compat import Statistics.Types (mkCL,cl95) import Text.PrettyPrint.ANSI.Leijen (Doc, text) import qualified Data.Map as M-import Prelude -- | How to match a benchmark name. data MatchType = Prefix@@ -82,7 +80,6 @@ defaultConfig :: Config defaultConfig = Config { confInterval = cl95- , forceGC = True , timeLimit = 5 , resamples = 1000 , regressions = []@@ -132,8 +129,6 @@ <$> option (mkCL <$> range 0.001 0.999) (long "ci" <> short 'I' <> metavar "CI" <> value confInterval <> help "Confidence interval")- <*> (not <$> switch (long "no-gc" <> short 'G' <>- help "Do not collect garbage between iterations")) <*> option (range 0.1 86400) (long "time-limit" <> short 'L' <> metavar "SECS" <> value timeLimit <> help "Time limit to run a benchmark")
Criterion/Measurement.hs view
@@ -5,12 +5,6 @@ {-# LANGUAGE BangPatterns, CPP, ForeignFunctionInterface, ScopedTypeVariables #-} -#if MIN_VERSION_base(4,10,0)--- Disable deprecation warnings for now until we remove the use of getGCStats--- and applyGCStats for good-{-# OPTIONS_GHC -Wno-deprecations #-}-#endif- -- | -- Module : Criterion.Measurement -- Copyright : (c) 2009-2014 Bryan O'Sullivan@@ -38,13 +32,9 @@ , measured , applyGCStatistics , threshold- -- * Deprecated- , getGCStats- , applyGCStats ) where import Criterion.Types (Benchmarkable(..), Measured(..))-import Control.Applicative ((<*)) import Control.DeepSeq (NFData(rnf)) import Control.Exception (finally,evaluate) import Data.Data (Data, Typeable)@@ -52,10 +42,13 @@ import Data.List (unfoldr) import Data.Word (Word64) import GHC.Generics (Generic)-import GHC.Stats (GCStats(..)) #if MIN_VERSION_base(4,10,0) import GHC.Stats (RTSStats(..), GCDetails(..))+#else+import GHC.Stats (GCStats(..)) #endif+import Prelude ()+import Prelude.Compat import System.Mem (performGC) import Text.Printf (printf) import qualified Control.Exception as Exc@@ -66,9 +59,9 @@ -- 'gcStatsCurrentBytesUsed' and 'gcStatsCurrentBytesSlop' all are cumulative values since -- the program started. ----- 'GCStatistics' is cargo-culted from the 'GCStats' data type that "GHC.Stats"--- has. Since 'GCStats' was marked as deprecated and will be removed in GHC 8.4,--- we use 'GCStatistics' to provide a backwards-compatible view of GC statistics.+-- 'GCStatistics' is cargo-culted from the @GCStats@ data type that "GHC.Stats"+-- used to export. Since @GCStats@ was removed in GHC 8.4, @criterion@ uses+-- 'GCStatistics' to provide a backwards-compatible view of GC statistics. data GCStatistics = GCStatistics { -- | Total number of bytes allocated gcStatsBytesAllocated :: !Int64@@ -115,18 +108,6 @@ -- | Try to get GC statistics, bearing in mind that the GHC runtime -- will throw an exception if statistics collection was not enabled -- using \"@+RTS -T@\".-{-# DEPRECATED getGCStats- ["GCStats has been deprecated in GHC 8.2. As a consequence,",- "getGCStats has also been deprecated in favor of getGCStatistics.",- "getGCStats will be removed in the next major criterion release."] #-}-getGCStats :: IO (Maybe GCStats)-getGCStats =- (Just `fmap` Stats.getGCStats) `Exc.catch` \(_::Exc.SomeException) ->- return Nothing---- | Try to get GC statistics, bearing in mind that the GHC runtime--- will throw an exception if statistics collection was not enabled--- using \"@+RTS -T@\". getGCStatistics :: IO (Maybe GCStatistics) #if MIN_VERSION_base(4,10,0) -- Use RTSStats/GCDetails to gather GC stats@@ -139,20 +120,20 @@ nsToSecs ns = fromIntegral ns * 1.0E-9 return $ Just GCStatistics {- gcStatsBytesAllocated = fromIntegral $ gcdetails_allocated_bytes gcdetails+ gcStatsBytesAllocated = fromIntegral $ allocated_bytes stats , gcStatsNumGcs = fromIntegral $ gcs stats , gcStatsMaxBytesUsed = fromIntegral $ max_live_bytes stats , gcStatsNumByteUsageSamples = fromIntegral $ major_gcs stats , gcStatsCumulativeBytesUsed = fromIntegral $ cumulative_live_bytes stats- , gcStatsBytesCopied = fromIntegral $ gcdetails_copied_bytes gcdetails+ , gcStatsBytesCopied = fromIntegral $ copied_bytes stats , gcStatsCurrentBytesUsed = fromIntegral $ gcdetails_live_bytes gcdetails , gcStatsCurrentBytesSlop = fromIntegral $ gcdetails_slop_bytes gcdetails , gcStatsMaxBytesSlop = fromIntegral $ max_slop_bytes stats , gcStatsPeakMegabytesAllocated = fromIntegral (max_mem_in_use_bytes stats) `quot` (1024*1024) , gcStatsMutatorCpuSeconds = nsToSecs $ mutator_cpu_ns stats , gcStatsMutatorWallSeconds = nsToSecs $ mutator_elapsed_ns stats- , gcStatsGcCpuSeconds = nsToSecs $ gcdetails_cpu_ns gcdetails- , gcStatsGcWallSeconds = nsToSecs $ gcdetails_elapsed_ns gcdetails+ , gcStatsGcCpuSeconds = nsToSecs $ gc_cpu_ns stats+ , gcStatsGcWallSeconds = nsToSecs $ gc_elapsed_ns stats , gcStatsCpuSeconds = nsToSecs $ cpu_ns stats , gcStatsWallSeconds = nsToSecs $ elapsed_ns stats }@@ -188,21 +169,21 @@ measure :: Benchmarkable -- ^ Operation to benchmark. -> Int64 -- ^ Number of iterations. -> IO (Measured, Double)-measure bm iters = runBenchmarkable bm iters addResults $ \act -> do+measure bm iters = runBenchmarkable bm iters addResults $ \ !n act -> do startStats <- getGCStatistics startTime <- getTime startCpuTime <- getCPUTime startCycles <- getCycles act+ endStats <- getGCStatistics endTime <- getTime endCpuTime <- getCPUTime endCycles <- getCycles- endStats <- getGCStatistics let !m = applyGCStatistics endStats startStats $ measured { measTime = max 0 (endTime - startTime) , measCpuTime = max 0 (endCpuTime - startCpuTime) , measCycles = max 0 (fromIntegral (endCycles - startCycles))- , measIters = iters+ , measIters = n } return (m, endTime) where@@ -240,7 +221,7 @@ threshold = 0.03 {-# INLINE threshold #-} -runBenchmarkable :: Benchmarkable -> Int64 -> (a -> a -> a) -> (IO () -> IO a) -> IO a+runBenchmarkable :: Benchmarkable -> Int64 -> (a -> a -> a) -> (Int64 -> IO () -> IO a) -> IO a runBenchmarkable Benchmarkable{..} i comb f | perRun = work >>= go (i - 1) | otherwise = work@@ -259,12 +240,12 @@ clean `seq` run `seq` evaluate $ rnf env performGC- f run `finally` clean <* performGC+ f count run `finally` clean <* performGC {-# INLINE work #-} {-# INLINE runBenchmarkable #-} runBenchmarkable_ :: Benchmarkable -> Int64 -> IO ()-runBenchmarkable_ bm i = runBenchmarkable bm i (\() () -> ()) id+runBenchmarkable_ bm i = runBenchmarkable bm i (\() () -> ()) (const id) {-# INLINE runBenchmarkable_ #-} -- | Run a single benchmark, and return measurements collected while@@ -331,30 +312,6 @@ -- | Apply the difference between two sets of GC statistics to a -- measurement.-{-# DEPRECATED applyGCStats- ["GCStats has been deprecated in GHC 8.2. As a consequence,",- "applyGCStats has also been deprecated in favor of applyGCStatistics.",- "applyGCStats will be removed in the next major criterion release."] #-}-applyGCStats :: Maybe GCStats- -- ^ Statistics gathered at the __end__ of a run.- -> Maybe GCStats- -- ^ Statistics gathered at the __beginning__ of a run.- -> Measured- -- ^ Value to \"modify\".- -> Measured-applyGCStats (Just end) (Just start) m = m {- measAllocated = diff bytesAllocated- , measNumGcs = diff numGcs- , measBytesCopied = diff bytesCopied- , measMutatorWallSeconds = diff mutatorWallSeconds- , measMutatorCpuSeconds = diff mutatorCpuSeconds- , measGcWallSeconds = diff gcWallSeconds- , measGcCpuSeconds = diff gcCpuSeconds- } where diff f = f end - f start-applyGCStats _ _ m = m---- | Apply the difference between two sets of GC statistics to a--- measurement. applyGCStatistics :: Maybe GCStatistics -- ^ Statistics gathered at the __end__ of a run. -> Maybe GCStatistics@@ -381,11 +338,7 @@ | k < 0 = '-' : secs (-k) | k >= 1 = k `with` "s" | k >= 1e-3 = (k*1e3) `with` "ms"-#ifdef mingw32_HOST_OS- | k >= 1e-6 = (k*1e6) `with` "us"-#else | k >= 1e-6 = (k*1e6) `with` "μs"-#endif | k >= 1e-9 = (k*1e9) `with` "ns" | k >= 1e-12 = (k*1e12) `with` "ps" | k >= 1e-15 = (k*1e15) `with` "fs"
Criterion/Monad/Internal.hs view
@@ -17,16 +17,14 @@ , Crit(..) ) where --- Temporary: to support pre-AMP GHC 7.8.4:-import Control.Applicative- import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask) import Control.Monad.Reader (MonadReader(..), ReaderT) import Control.Monad.Trans (MonadIO) import Criterion.Types (Config) import Data.IORef (IORef)+import Prelude ()+import Prelude.Compat import System.Random.MWC (GenIO)-import Prelude data Crit = Crit { config :: !Config
Criterion/Types.hs view
@@ -72,9 +72,7 @@ , DataRecord(..) ) where --- Temporary: to support pre-AMP GHC 7.8.4:-import Control.Applicative-import Data.Monoid+-- Temporary: to support pre-SMP import Data.Semigroup import Control.DeepSeq (NFData(rnf))@@ -86,11 +84,12 @@ import Data.Int (Int64) import Data.Map (Map, fromList) 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 ()-import Prelude -- | Control the amount of information displayed. data Verbosity = Quiet@@ -104,11 +103,6 @@ confInterval :: St.CL Double -- ^ Confidence interval for bootstrap estimation (greater than -- 0, less than 1).- , forceGC :: Bool- -- ^ /Obsolete, unused/. This option used to force garbage- -- collection between every benchmark run, but it no longer has- -- an effect (we now unconditionally force garbage collection).- -- This option remains solely for backwards API compatibility. , timeLimit :: Double -- ^ Number of seconds to run a single benchmark. (In practice, -- execution time will very slightly exceed this limit.)@@ -133,8 +127,6 @@ , template :: FilePath -- ^ Template file to use if writing a report. } deriving (Eq, Read, Show, Typeable, Data, Generic)-{-# DEPRECATED forceGC- ["forceGC will be removed in the next major criterion release."] #-} -- | A pure function or impure action that can be benchmarked. The -- 'Int64' parameter indicates the number of times to run the given
README.markdown view
@@ -1,6 +1,6 @@ # Criterion: robust, reliable performance measurement -[](https://travis-ci.org/bos/criterion)+[](https://hackage.haskell.org/package/criterion) [](https://travis-ci.org/bos/criterion) This package provides the Criterion module, a Haskell library for measuring and analysing software performance.
app/Options.hs view
@@ -7,11 +7,13 @@ , versionInfo ) where -import Data.Monoid ((<>), mconcat)-import Data.Version (showVersion) import Data.Data (Data, Typeable)+import Data.Semigroup ((<>))+import Data.Version (showVersion) import GHC.Generics (Generic) import Paths_criterion (version)+import Prelude ()+import Prelude.Compat import Options.Applicative data CommandLine
changelog.md view
@@ -1,3 +1,36 @@+1.3.0.0++* `criterion` was previously reporting the following statistics incorrectly+ on GHC 8.2 and later:++ * `gcStatsBytesAllocated`+ * `gcStatsBytesCopied`+ * `gcStatsGcCpuSeconds`+ * `gcStatsGcWallSeconds`++ This has been fixed.++* The type signature of `runBenchmarkable` has changed from:++ ```haskell+ Benchmarkable -> Int64 -> (a -> a -> a) -> (IO () -> IO a) -> IO a+ ```++ to:++ ```haskell+ Benchmarkable -> Int64 -> (a -> a -> a) -> (Int64 -> IO () -> IO a) -> IO a+ ```++ The extra `Int64` argument represents how many iterations are being timed.++* Remove the deprecated `getGCStats` and `applyGCStats` functions (which have+ been replaced by `getGCStatistics` and `applyGCStatistics`).+* Remove the deprecated `forceGC` field of `Config`, as well as the+ corresponding `--no-gc` command-line option.+* The header in generated JSON output mistakenly used the string `"criterio"`.+ This has been corrected to `"criterion"`.+ 1.2.6.0 * Add error bars and zoomable navigation to generated HTML report graphs.
criterion.cabal view
@@ -1,5 +1,5 @@ name: criterion-version: 1.2.6.0+version: 1.3.0.0 synopsis: Robust, reliable performance measurement and analysis license: BSD3 license-file: LICENSE@@ -23,7 +23,8 @@ GHC==7.8.4, GHC==7.10.3, GHC==8.0.2,- GHC==8.2.2+ GHC==8.2.2,+ GHC==8.4.1 data-files: templates/*.css@@ -145,8 +146,10 @@ Build-Depends: base,+ base-compat, criterion,- optparse-applicative >= 0.13+ optparse-applicative >= 0.13,+ semigroups if impl(ghc < 7.6) build-depends:@@ -206,6 +209,7 @@ build-depends: HUnit, base,+ base-compat, bytestring, criterion, deepseq,
examples/Maps.hs view
@@ -1,6 +1,7 @@ -- Benchmark the cost of creating various types of map. -{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}+{-# LANGUAGE CPP, FlexibleContexts, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} import Criterion.Main import Data.ByteString (ByteString, pack)@@ -15,6 +16,10 @@ import qualified Data.Vector.Generic as G import qualified Data.Vector.Unboxed as U +#if !MIN_VERSION_bytestring(0,10,0)+import Control.DeepSeq (NFData (..))+#endif+ type V = U.Vector Int type B = V.Vector ByteString @@ -88,3 +93,8 @@ value :: Int value = 31337++#if !MIN_VERSION_bytestring(0,10,0)+instance NFData ByteString where+ rnf bs = bs `seq` ()+#endif
examples/criterion-examples.cabal view
@@ -1,15 +1,23 @@ name: criterion-examples version: 0 synopsis: Examples for the criterion benchmarking system-description: Examples for the criterion benchmarking system+description: Examples for the criterion benchmarking system. homepage: https://github.com/bos/criterion license: BSD3-license-file: ../LICENSE+license-file: LICENSE author: Bryan O'Sullivan <bos@serpentine.com> maintainer: Bryan O'Sullivan <bos@serpentine.com> category: Benchmarks build-type: Simple cabal-version: >=1.8+tested-with:+ GHC==7.4.2,+ GHC==7.6.3,+ GHC==7.8.4,+ GHC==7.10.3,+ GHC==8.0.2,+ GHC==8.2.2,+ GHC==8.4.1 executable fibber main-is: Fibber.hs@@ -40,6 +48,7 @@ containers, critbit, criterion,+ deepseq, hashable, mwc-random, unordered-containers,
tests/Cleanup.hs view
@@ -6,11 +6,13 @@ import Criterion.Main (Benchmark, bench, nfIO) import Criterion.Types (Config(..), Verbosity(Quiet))-import Control.Applicative (pure) import Control.DeepSeq (NFData(..)) import Control.Exception (Exception, try, throwIO) import Control.Monad (when)+import Data.ByteString (ByteString) import Data.Typeable (Typeable)+import Prelude ()+import Prelude.Compat import System.Directory (doesFileExist, removeFile) import System.Environment (withArgs) import System.IO ( Handle, IOMode(ReadWriteMode), SeekMode(AbsoluteSeek)@@ -19,7 +21,6 @@ import Test.Tasty.HUnit (testCase) import Test.HUnit (assertFailure) import qualified Criterion.Main as C-import Data.ByteString (ByteString) import qualified Data.ByteString as BS instance NFData Handle where
tests/Sanity.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} import Criterion.Main (bench, bgroup, env, whnf) import System.Environment (getEnv, withArgs)