criterion-measurement 0.2.0.0 → 0.2.1.0
raw patch · 3 files changed
+42/−15 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Criterion.Measurement.Types.Internal: SPEC :: SPEC
+ Criterion.Measurement.Types.Internal: SPEC2 :: SPEC
+ Criterion.Measurement.Types.Internal: data SPEC
Files
- changelog.md +5/−0
- criterion-measurement.cabal +2/−4
- src/Criterion/Measurement/Types/Internal.hs +35/−11
changelog.md view
@@ -1,3 +1,8 @@+0.2.1.0++* Make the behavior of the benchmarking functions independent of the+ `-fspec-const-count` limit.+ 0.2.0.0 * Add a `measPeakMbAllocated` field to `Measured` for reporting maximum
criterion-measurement.cabal view
@@ -1,5 +1,5 @@ name: criterion-measurement-version: 0.2.0.0+version: 0.2.1.0 synopsis: Criterion measurement functionality and associated types description: Measurement-related functionality extracted from Criterion, with minimal dependencies. The rationale for this is to enable alternative analysis front-ends. homepage: https://github.com/haskell/criterion@@ -42,10 +42,8 @@ , binary >= 0.5.1.0 , containers , deepseq >= 1.1.0.0+ , ghc-prim , vector >= 0.7.1- if impl(ghc < 7.6)- build-depends:- ghc-prim default-language: Haskell2010 ghc-options: -Wall -funbox-strict-fields
src/Criterion/Measurement/Types/Internal.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} -- Ensure that nf' and whnf' are always optimized, even if -- criterion-measurement is compiled with -O0 or -fprof-auto (see #184).@@ -17,11 +18,22 @@ -- Portability : GHC -- -- Exports 'fakeEnvironment'.-module Criterion.Measurement.Types.Internal (fakeEnvironment, nf', whnf') where+module Criterion.Measurement.Types.Internal+ ( fakeEnvironment+ , nf'+ , whnf'+ , SPEC(..)+ ) where import Data.Int (Int64) import Control.Exception +#if MIN_VERSION_ghc_prim(0,3,1)+import GHC.Types (SPEC(..))+#else+import GHC.Exts (SpecConstrAnnotation(..))+#endif+ -- | A dummy environment that is passed to functions that create benchmarks -- from environments when no concrete environment is available. fakeEnvironment :: env@@ -46,6 +58,9 @@ -- benchmark code itself could be changed by the user's optimization level. By -- marking them @NOINLINE@, the core benchmark code is always the same. --+-- To ensure that the behavior of these functions remains independent of+-- -fspec-constr-count, we force SpecConst optimization by passing SPEC.+-- -- Finally, it's important that both branches of the loop depend on the state -- token from the IO action. This is achieved by using `evaluate` rather than `let !y = f x` -- in order to force the value to whnf. `evaluate` is in the IO monad and therefore the state@@ -61,21 +76,30 @@ -- | Generate a function which applies an argument to a function a -- given number of times, reducing the result to normal form. nf' :: (b -> ()) -> (a -> b) -> a -> (Int64 -> IO ())-nf' reduce f x = go+nf' reduce f x = go SPEC where- go n | n <= 0 = return ()- | otherwise = do- y <- evaluate (f x)- reduce y `seq` go (n-1)+ go :: SPEC -> Int64 -> IO ()+ go !_ n+ | n <= 0 = return ()+ | otherwise = do+ y <- evaluate (f x)+ reduce y `seq` go SPEC (n-1) {-# NOINLINE nf' #-} -- | Generate a function which applies an argument to a function a -- given number of times. whnf' :: (a -> b) -> a -> (Int64 -> IO ())-whnf' f x = go+whnf' f x = go SPEC where- go n | n <= 0 = return ()- | otherwise = do- _ <- evaluate (f x)- go (n-1)+ go :: SPEC -> Int64 -> IO ()+ go !_ n+ | n <= 0 = return ()+ | otherwise = do+ _ <- evaluate (f x)+ go SPEC (n-1) {-# NOINLINE whnf' #-}++#if !(MIN_VERSION_ghc_prim(0,3,1))+data SPEC = SPEC | SPEC2+{-# ANN type SPEC ForceSpecConstr #-}+#endif