benchpress 0.2.2.7 → 0.2.2.8
raw patch · 4 files changed
+79/−37 lines, 4 filesdep +bytestringdep ~basedep ~timenew-component:exe:examplePVP ok
version bump matches the API change (PVP)
Dependencies added: bytestring
Dependency ranges changed: base, time
API changes (from Hackage documentation)
Files
- Math/Statistics.hs +4/−4
- Test/BenchPress.hs +31/−30
- benchpress.cabal +16/−3
- example/Main.hs +28/−0
Math/Statistics.hs view
@@ -4,7 +4,7 @@ -- Copyright : (c) Johan Tibell 2008 -- License : BSD3-style (see LICENSE) ----- Maintainer : johan.tibell@gmail.com+-- Maintainer : me@willsewell.com -- Stability : experimental -- Portability : portable --@@ -27,7 +27,7 @@ where go :: Floating a => a -> Int -> [a] -> a go m _ [] = m- go m n (x:xs) = go (m + (x - m) / (fromIntegral $ n + 1)) (n + 1) xs+ go m n (x:xs) = go (m + (x - m) / fromIntegral (n + 1)) (n + 1) xs -- | Median. median :: (Floating a, Ord a) => [a] -> a@@ -45,11 +45,11 @@ -- | Numerically stable sample variance. variance :: Floating a => [a] -> a-variance xs = (go 0 0 0 xs) / (fromIntegral $ length xs - 1)+variance xs = go 0 0 0 xs / fromIntegral (length xs - 1) where go :: Floating a => a -> Int -> a -> [a] -> a go _ _ s [] = s go m n s (x:xs') = go nm (n + 1) (s + delta * (x - nm)) xs' where delta = x - m- nm = m + delta / (fromIntegral $ n + 1)+ nm = m + delta / fromIntegral (n + 1)
Test/BenchPress.hs view
@@ -4,7 +4,7 @@ -- Copyright : (c) Johan Tibell 2008 -- License : BSD3-style (see LICENSE) ----- Maintainer : johan.tibell@gmail.com+-- Maintainer : me@willsewell.com -- Stability : experimental -- Portability : portable --@@ -15,6 +15,7 @@ -- -- Here's an example showing a benchmark of copying a file: --+-- > import Control.Monad (when) -- > import qualified Data.ByteString as B -- > import System.IO -- > import Test.BenchPress@@ -32,9 +33,8 @@ -- > go = do -- > bs <- B.hGet inf blockSize -- > let numRead = B.length bs--- > if numRead > 0--- > then B.hPut outf bs >> go--- > else return ()+-- > when (numRead > 0) $+-- > B.hPut outf bs >> go -- > -- > main :: IO () -- > main = bench 100 $ do@@ -73,8 +73,6 @@ -- --------------------------------------------------------------------- -- Running a benchmark --- TODO: Make sure that iters is > 0.- -- | @benchmark iters setup teardown action@ runs @action@ @iters@ -- times measuring the execution time of each run. @setup@ and -- @teardown@ are run before and after each run respectively.@@ -82,27 +80,30 @@ -- statistics for both the measured CPU times and wall clock times, in -- that order. benchmark :: Int -> IO a -> (a -> IO b) -> (a -> IO c) -> IO (Stats, Stats)-benchmark iters setup teardown action = do- (cpuTimes, wallTimes) <- unzip `fmap` go iters- let xs = sort cpuTimes- cpuStats = Stats- { min = head xs- , mean = Math.mean xs- , stddev = Math.stddev xs- , median = Math.median xs- , max = last xs- , percentiles = percentiles' xs- }- ys = sort wallTimes- wallStats = Stats- { min = head ys- , mean = Math.mean ys- , stddev = Math.stddev ys- , median = Math.median ys- , max = last ys- , percentiles = percentiles' ys- }- return (cpuStats, wallStats)+benchmark iters setup teardown action =+ if iters < 1+ then error "benchmark: iters must be greater than 0"+ else do+ (cpuTimes, wallTimes) <- unzip `fmap` go iters+ let xs = sort cpuTimes+ cpuStats = Stats+ { min = head xs+ , mean = Math.mean xs+ , stddev = Math.stddev xs+ , median = Math.median xs+ , max = last xs+ , percentiles = percentiles' xs+ }+ ys = sort wallTimes+ wallStats = Stats+ { min = head ys+ , mean = Math.mean ys+ , stddev = Math.stddev ys+ , median = Math.median ys+ , max = last ys+ , percentiles = percentiles' ys+ }+ return (cpuStats, wallStats) where go 0 = return [] go n = do@@ -176,7 +177,7 @@ putStrLn "Percentiles (ms)" putStr psTbl where- columns = map $ \(p, value) -> printf " %3d%% %5.3f" p value+ columns = map (uncurry $ printf " %3d%% %5.3f") colWidth = columnWidth [stats] psTbl = unlines $ columns (percentiles stats) @@ -222,7 +223,7 @@ printSummaryHeader :: Int -> Int -> IO () printSummaryHeader lblLen colWidth = do putStrLn "Times (ms)"- putStr $ (replicate lblLen ' ') ++ " "+ putStr $ replicate lblLen ' ' ++ " " putStrLn $ intercalate " " $ map (padHeader colWidth) headers -- | Print a row showing a summary of the given stats.@@ -237,7 +238,7 @@ -- | Compute percentiles given a list of execution times in ascending -- order. percentiles' :: [Double] -> [(Int, Double)]-percentiles' xs = zipWith (\p ys -> (p, ys !! (rank p))) ps (repeat xs)+percentiles' xs = map (\p -> (p, xs !! rank p)) ps where n = length xs rank p = ceiling ((fromIntegral n / 100) * fromIntegral p :: Double) - 1
benchpress.cabal view
@@ -1,5 +1,5 @@ name: benchpress-version: 0.2.2.7+version: 0.2.2.8 synopsis: Micro-benchmarking with detailed statistics. Description: Benchmarks actions and produces statistics such as min, mean, median, standard deviation,@@ -20,8 +20,21 @@ other-modules: Math.Statistics - build-depends: base >= 2.0 && < 4.9,+ build-depends: base >= 2.0 && < 4.10, mtl >= 1 && < 2.3,- time >= 1 && < 1.6+ time >= 1 && < 1.7++ ghc-options: -funbox-strict-fields -Wall++executable example+ main-is: Main.hs++ -- This is not in build-depends for cabal 1.2 compatibility (requires 1.8)+ other-modules: Test.BenchPress++ hs-source-dirs: example, .++ build-depends: base,+ bytestring ghc-options: -funbox-strict-fields -Wall
+ example/Main.hs view
@@ -0,0 +1,28 @@+import Control.Monad (when)+import qualified Data.ByteString as B+import System.IO+import Test.BenchPress++inpath, outpath :: String+inpath = "/tmp/infile"+outpath = "/tmp/outfile"++blockSize :: Int+blockSize = 4 * 1024++copyUsingByteString :: Handle -> Handle -> IO ()+copyUsingByteString inf outf = go+ where+ go = do+ bs <- B.hGet inf blockSize+ let numRead = B.length bs+ when (numRead > 0) $+ B.hPut outf bs >> go++main :: IO ()+main = bench 100 $ do+ inf <- openBinaryFile inpath ReadMode+ outf <- openBinaryFile outpath WriteMode+ copyUsingByteString inf outf+ hClose outf+ hClose inf