hashtables-1.0.1.5: benchmark/src/Criterion/Collection/Types.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | The criterion collection is a set of utilities for benchmarking data
-- structures using criterion
-- (<http://hackage.haskell.org/package/criterion>).
--
-- The criterion collection allows you to test the /per-operation/ asymptotic
-- performance of your data structures under a variety of simulated
-- workloads. For testing a hash table, for example, you might be interested
-- in:
--
-- * how lookup and insert performance changes as the number of elements in
-- your hash table grows
--
-- * how lookup performance changes depending on the distribution of the
-- lookup keys; you might expect a heavily skewed lookup distribution, where
-- most of the requests are for a small subset of the keys, to have
-- different performance characteristics than a set of lookups for keys
-- uniformly distributed in the keyspace.
--
-- * how the hashtable performs under a mixed workload of inserts, deletes,
-- and lookups.
--
-- Whereas "Criterion" allows you to run a single benchmark a number of times
-- to see how fast it runs, @criterion-collection@ makes performance-testing
-- data structures easier by decoupling benchmarking from workload generation,
-- allowing you to see in-depth how performance changes as the input size
-- varies.
--
-- To test your data structure using @criterion-collection@, you provide the
-- following:
--
-- 1. A datatype which models the set of data structure operations you're
-- interested in testing. For instance, for our hashtable example, your
-- datatype might look like:
--
-- > data Operation k =
-- > -- | Insert a k-v pair into the collection. If k existed, we
-- > -- should update the mapping.
-- > Insert {-# UNPACK #-} !k
-- > {-# UNPACK #-} !Int
-- > -- | Lookup a key in the mapping.
-- > | Lookup {-# UNPACK #-} !k
-- > -- | Delete a key from the mapping.
-- > | Delete {-# UNPACK #-} !k
-- > deriving (Show)
-- >
-- >
-- > instance (NFData k) => NFData (Operation k) where
-- > rnf (Insert k v) = rnf k `seq` rnf v
-- > rnf (Lookup k) = rnf k
-- > rnf (Delete k) = rnf k
--
-- 2. A function which, given an operation, runs it on your datastructure.
--
-- 3. A \"ground state\" for your datastructure, usually \"empty\". You can
-- test both pure data structures and data structures in 'IO'.
--
-- 4. One or more \"workload simulators\" which, given a random number
-- generator and an input size, give you back some functions to generate
-- workloads:
--
-- a) to prepopulate the data structure prior to the test
--
-- b) to test the data structure with.
--
-- (Side note: the reason @criterion-collection@ asks you to reify the
-- operation type instead of just generating a list of mutation functions of
-- type @[m -> m]@ is so you can test multiple datastructures under the same
-- workload.)
module Criterion.Collection.Types
( Workload(..)
, WorkloadGenerator
, WorkloadMonad
, runWorkloadMonad
, getRNG
, DataStructure
, emptyData
, runOperation
, setupData
, setupDataIO
) where
------------------------------------------------------------------------------
import Criterion.Collection.Internal.Types