criterion-0.1: Criterion/Types.hs
-- |
-- Module : Criterion.Types
-- Copyright : (c) Bryan O'Sullivan 2009
--
-- License : BSD-style
-- Maintainer : bos@serpentine.com
-- Stability : experimental
-- Portability : GHC
--
-- Types for benchmarking.
--
-- The core class is 'Benchmarkable', which admits both pure functions
-- and 'IO' actions.
--
-- For a pure function of type @Int -> a@, the benchmarking harness
-- calls this function repeatedly, each time with a different 'Int'
-- argument, and reduces the result the function returns to weak head
-- normal form. If you need the result reduced to normal form, that
-- is your responsibility.
--
-- For an action of type @IO a@, the benchmarking harness calls the
-- action repeatedly, but does not reduce the result.
{-# LANGUAGE FlexibleInstances, GADTs #-}
module Criterion.Types
(
Benchmarkable(..)
, Benchmark(..)
, bench
, bgroup
, benchNames
) where
import Control.Exception (evaluate)
-- | A benchmarkable function or action.
class Benchmarkable b where
run :: b -> Int -> IO ()
instance Benchmarkable (Int -> a) where
run f u = evaluate (f u) >> return ()
instance Benchmarkable (IO a) where
run a _ = a >> return ()
-- | A benchmark may consist of either a single 'Benchmarkable' item
-- with a name, created with 'bench', or a (possibly nested) group of
-- 'Benchmark's, created with 'bgroup'.
data Benchmark where
Benchmark :: Benchmarkable b => String -> b -> Benchmark
BenchGroup :: String -> [Benchmark] -> Benchmark
-- | Create a single benchmark.
bench :: Benchmarkable b =>
String -- ^ A name to identify the benchmark.
-> b
-> Benchmark
bench = Benchmark
-- | Group several benchmarks together under a common name.
bgroup :: String -- ^ A name to identify the group of benchmarks.
-> [Benchmark] -- ^ Benchmarks to group under this name.
-> Benchmark
bgroup = BenchGroup
-- | Retrieve the names of all benchmarks. Grouped benchmarks are
-- prefixed with the name of the group they're in.
benchNames :: Benchmark -> [String]
benchNames (Benchmark d _) = [d]
benchNames (BenchGroup d bs) = map ((d ++ "/") ++) . concatMap benchNames $ bs
instance Show Benchmark where
show (Benchmark d _) = ("Benchmark " ++ show d)
show (BenchGroup d _) = ("BenchGroup " ++ show d)