BSD-3-Clause licensed by Bryan O'Sullivan
Maintained by Ryan Scott
This version can be pinned in stack with:criterion-,5616

Criterion: robust, reliable performance measurement

Hackage Build Status

This package provides the Criterion module, a Haskell library for measuring and analysing software performance.

To get started, read the online tutorial, and take a look at the programs in the examples directory.

Get involved!

Please report bugs via the github issue tracker.

Master github repository:

  • git clone


This library is written and maintained by Bryan O’Sullivan, [email protected].


  • Remove a use of the partial head function within criterion.

  • Require optparse-applicative-0.18.* as the minimum and add an explicit dependency on prettyprinter and prettyprinter-ansi-terminal.

  • Support building with optparse-applicative-0.18.*.

  • criterion-measurement- adds the measPeakMbAllocated field to Measured for reporting maximum megabytes allocated. Since criterion re-exports Measured from Criterion.Types, this change affects criterion as well. Naturally, this affects the behavior of Measured’s {To,From}JSON and Binary instances.
  • Fix a bug in which the --help text for the --match option was printed twice in criterion applications.

  • Allow building with optparse-applicative-0.17.*.

  • Fix a bug introduced in version in which benchmark names that include double quotes would produce broken HTML reports.

  • Allow building with aeson-

  • Fix a bug in which the defaultMainWith function would not use the regressions values specified in the Config argument. This bug only affected criterion the library—uses of the --regressions flag from criterion executables themselves were unaffected.

  • Fix a bug where HTML reports failed to escape JSON properly.

  • The HTML reports have been reworked.

    • The flot plotting library (js-flot on Hackage) has been replaced by Chart.js (js-chart).
    • Most practical changes focus on improving the functionality of the overview chart:
      • It now supports logarithmic scale (#213). The scale can be toggled by clicking the x-axis.
      • Manual zooming has been replaced by clicking to focus a single bar.
      • It now supports a variety of sort orders.
      • The legend can now be toggled on/off and is hidden by default.
      • Clicking the name of a group in the legend shows/hides all bars in that group.
    • The regression line on the scatter plot shows confidence interval.
    • Better support for mobile and print.
    • JSON escaping has been made more robust by no longer directly injecting reports as JavaScript code.

  • Warn if an HTML report name contains newlines, and replace newlines with whitespace to avoid syntax errors in the report itself.

  • Use unescaped HTML in the json.tpl template.

  • Bundle criterion-examplesLICENSE file.

  • Allow building with base-compat-batteries-0.11.

  • Fix the build on old GHCs with the embed-data-files flag.
  • Require transformers-compat-0.6.4 or later.

  • Add parserWith, which allows creating a criterion command-line interface using a custom optparse-applicative Parser. This is usefule for sitations where one wants to add additional command-line arguments to the default ones that criterion provides.

    For an example of how to use parserWith, refer to examples/ExtensibleCLI.hs.

  • Tweak the way the graph in the HTML overview zooms:

    • Zooming all the way out resets to the default view (instead of continuing to zoom out towards empty space).
    • Panning all the way to the right resets to the default view in which zero is left-aligned (instead of continuing to pan off the edge of the graph).
    • Panning and zooming only affecs the x-axis, so all results remain in-frame.

  • Make more functions (e.g., runMode) able to print the µ character on non-UTF-8 encodings.

  • Fix a bug in which HTML reports would render incorrectly when including benchmark names containing apostrophes.

  • Only incur a dependency on fail on old GHCs.

  • Add a MonadFail Criterion instance.

  • Add some documentation in Criterion.Main about criterion-measurement’s new nfAppIO and whnfAppIO functions, which criterion reexports.

  • Move the measurement functionality of criterion into a standalone package, criterion-measurement. In particular, cbits/ and Criterion.Measurement are now in criterion-measurement, along with the relevant definitions of Criterion.Types and Criterion.Types.Internal (both of which are now under the Criterion.Measurement.* namespace). Consequently, criterion now depends on criterion-measurement.

    This will let other libraries (e.g. alternative statistical analysis front-ends) to import the measurement functionality alone as a lightweight dependency.

  • Fix a bug on macOS and Windows where using runAndAnalyse and other lower-level benchmarking functions would result in an infinite loop.

  • Use base-compat-batteries.

  • We now do three samples for statistics:

    • performMinorGC before the first sample, to ensure it’s up to date.
    • Take another sample after the action, without a garbage collection, so we can gather legitimate readings on GC-related statistics.
    • Then performMinorGC and sample once more, so we can get up-to-date readings on other metrics.

    The type of applyGCStatistics has changed accordingly. Before, it was:

       Maybe GCStatistics -- ^ Statistics gathered at the end of a run.
    -> Maybe GCStatistics -- ^ Statistics gathered at the beginning of a run.
    -> Measured -> Measured

    Now, it is:

       Maybe GCStatistics -- ^ Statistics gathered at the end of a run, post-GC.
    -> Maybe GCStatistics -- ^ Statistics gathered at the end of a run, pre-GC.
    -> Maybe GCStatistics -- ^ Statistics gathered at the beginning of a run.
    -> Measured -> Measured

    When diffing GCStatistics in applyGCStatistics, we carefully choose whether to diff against the end stats pre- or post-GC.

  • Use performMinorGC rather than performGC to update garbage collection statistics. This improves the benchmark performance of fast functions on large objects.

  • Fix a bug in the ToJSON Measured instance which duplicated the mutator CPU seconds where GC CPU seconds should go.

  • Fix a bug in sample analysis which incorrectly accounted for overhead causing runtime errors and invalid results. Accordingly, the buggy getOverhead function has been removed.

  • Fix a bug in Measurement.measure which inflated the reported time taken for perRun benchmarks.

  • Reduce overhead of nf, whnf, nfIO, and whnfIO by removing allocation from the central loops.

  • 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:

    Benchmarkable -> Int64 -> (a -> a -> a) -> (IO () -> IO a) -> IO a


    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".

  • Add error bars and zoomable navigation to generated HTML report graphs.

    (Note that there have been reports that this feature can be somewhat unruly when using macOS and Firefox simultaneously. See for more details.)

  • Use a predetermined set of cycling colors for benchmark groups in HTML reports. This avoids a bug in earlier versions of criterion where benchmark group colors could be chosen that were almost completely white, which made them impossible to distinguish from the background.

  • Add an -fembed-data-files flag. Enabling this option will embed the data-files from criterion.cabal directly into the binary, producing a relocatable executable. (This has the downside of increasing the binary size significantly, so be warned.)

  • Fix issue where --help would display duplicate options.

  • Add a Semigroup instance for Outliers.

  • Improve the error messages that are thrown when forcing nonexistent benchmark environments.

  • Explicitly mark forceGC as deprecated. forceGC has not had any effect for several releases, and it will be removed in the next major criterion release.

  • Important bugfix: versions and were incorrectly displaying the lower and upper bounds for measured values on HTML reports.

  • Have criterion emit warnings if suspicious things happen during mustache template substitution when creating HTML reports. This can be useful when using custom templates with the --template flag.

  • Add GCStatistics, getGCStatistics, and applyGCStatistics to Criterion.Measurement. These are inteded to replace GCStats (which has been deprecated in base and will be removed in GHC 8.4), as well as getGCStats and applyGCStats, which have also been deprecated and will be removed in the next major criterion release.

  • Add new matchers for the --match flag:

    • --match pattern, which matches by searching for a given substring in benchmark paths.
    • --match ipattern, which is like --match pattern but case-insensitive.
  • Export Criterion.Main.Options.config.

  • Export Criterion.toBenchmarkable, which behaves like the Benchmarkable constructor did prior to criterion-

  • Use statistics-0.14.

  • Replace the hastache dependency with microstache.

  • Add support for per-run allocation/cleanup of the environment with perRunEnv and perRunEnvWithCleanup,

  • Add support for per-batch allocation/cleanup with perBatchEnv and perBatchEnvWithCleanup.

  • Add envWithCleanup, a variant of env with cleanup support.

  • Add the criterion-report executable, which creates reports from previously created JSON files.

  • Unicode output is now correctly printed on Windows.

  • Add Safe Haskell annotations.

  • Add --json option for writing reports in JSON rather than binary format. Also: various bugfixes related to this.

  • Use the js-jquery and js-flot libraries to substitute in JavaScript code into the default HTML report template.

  • Use the code-page library to ensure that criterion prints out Unicode characters (like ², which criterion uses in reports) in a UTF-8-compatible code page on Windows.

  • Give an explicit implementation for get in the Binary Regression instance. This should fix sporadic criterion failures with older versions of binary.

  • Use tasty instead of test-framework in the test suites.

  • Restore support for 32-bit Intel CPUs.

  • Restore build compatibilty with GHC 7.4.

  • If a benchmark uses Criterion.env in a non-lazy way, and you try to use --list to list benchmark names, you’ll now get an understandable error message instead of something cryptic.

  • We now flush stdout and stderr after printing messages, so that output is printed promptly even when piped (e.g. into a pager).

  • A new function runMode allows custom benchmarking applications to run benchmarks with control over the Mode used.

  • Added support for Linux on non-Intel CPUs.

  • This version supports GHC 8.

  • The --only-run option for benchmarks is renamed to --iters.

  • The dependency on the either package has been dropped in favour of a dependency on transformers-compat. This greatly reduces the number of packages criterion depends on. This shouldn’t affect the user-visible API.

  • The documentation claimed that environments were created only when needed, but this wasn’t implemented. (gh-76)

  • The package now compiles with GHC 7.10.

  • On Windows with a non-Unicode code page, printing results used to cause a crash. (gh-55)

  • Bump lower bound on optparse-applicative to 0.11 to handle yet more annoying API churn.

  • Added a lower bound of 0.10 on the optparse-applicative dependency, as there were major API changes between 0.9 and 0.10.