packages feed

criterion 0.1 → 0.1.2

raw patch · 5 files changed

+162/−31 lines, 5 files

Files

Criterion/Plot.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP, ScopedTypeVariables #-}  -- | -- Module      : Criterion.Plot@@ -19,13 +19,10 @@     ) where  import Criterion.Config-import Data.Accessor ((^=)) import Data.Array.Vector import Data.Char (isSpace, toLower) import Data.Foldable (forM_) import Data.List (group, intersperse)-import Graphics.Rendering.Chart hiding (Plot,c)-import Graphics.Rendering.Chart.Gtk (renderableToWindow) import Statistics.KernelDensity (Points, fromPoints) import Statistics.Types (Sample) import System.FilePath (pathSeparator)@@ -33,6 +30,14 @@ import Text.Printf (printf) import qualified Criterion.MultiMap as M +#ifdef HAVE_CHART+import Data.Accessor ((^=))+import Graphics.Rendering.Chart hiding (Plot,c)+import Graphics.Rendering.Chart.Gtk (renderableToWindow)+#else+import Criterion.IO (printError)+#endif+ plotWith :: Plot -> Config -> (PlotOutput -> IO ()) -> IO () plotWith p cfg plot =   case M.lookup p (cfgPlot cfg) of@@ -51,6 +56,7 @@     forM_ (fromU $ indexedU times) $ \(x :*: y) ->       putRow h [show x, show y] +#ifdef HAVE_CHART plotTiming (PDF x y) desc times =   renderableToPDFFile (renderTiming desc times) x y                       (mangle $ printf "%s timings %dx%d.pdf" desc x y)@@ -65,6 +71,11 @@  plotTiming (Window x y) desc times =   renderableToWindow (renderTiming desc times) x y+#else+plotTiming output _desc _times =+  printError "ERROR: output type %s not supported on this platform\n"+             (show output)+#endif  -- | Plot kernel density estimate. plotKDE :: PlotOutput           -- ^ The kind of output desired.@@ -79,6 +90,7 @@     forM_ (zip (fromU pdf) (fromU (fromPoints points))) $ \(x, y) ->       putRow h [show x, show y] +#ifdef HAVE_CHART plotKDE (PDF x y) desc points pdf =   renderableToPDFFile (renderKDE desc points pdf) x y                       (mangle $ printf "%s densities %dx%d.pdf" desc x y)@@ -93,7 +105,13 @@  plotKDE (Window x y) desc points pdf =     renderableToWindow (renderKDE desc points pdf) x y+#else+plotKDE output _desc _points _pdf =+  printError "ERROR: output type %s not supported on this platform\n"+             (show output)+#endif +#ifdef HAVE_CHART renderTiming :: String -> Sample -> Renderable () renderTiming desc times = toRenderable layout   where@@ -110,7 +128,9 @@     bottomAxis = laxis_title ^= "number of samples"                $ defaultLayoutAxis -    bars = plot_bars_values ^= (zip [0..] . map (:[]) . fromU $ times)+    bars = plot_bars_values ^= (zip [0.5,1.5..] . map (:[]) . fromU $ times)+         $ plot_bars_item_styles ^= [ (solidFillStyle c, Nothing) | c <- defaultColorSeq ]+         $ plot_bars_spacing ^= BarsFixGap 0          $ defaultPlotBars  renderKDE :: String -> Points -> UArr Double -> Renderable ()@@ -141,28 +161,6 @@ secAxis = la_labelf ^= secs         $ defaultLinearAxis -writeTo :: FilePath -> (Handle -> IO a) -> IO a-writeTo path = withBinaryFile path WriteMode--escapeCSV :: String -> String-escapeCSV xs | any (`elem`xs) escapes = '"' : concatMap esc xs ++ "\""-          | otherwise              = xs-    where esc '"' = "\"\""-          esc c   = [c]-          escapes = "\"\r\n,"--putRow :: Handle -> [String] -> IO ()-putRow h s = hPutStr h (concat (intersperse "," (map escapeCSV s)) ++ "\r\n")---- | Get rid of spaces and other potentially troublesome characters--- from output.-mangle :: String -> FilePath-mangle = concatMap (replace ((==) '-' . head) "-")-       . group-       . map (replace isSpace '-' . replace (==pathSeparator) '-' . toLower)-    where replace p r c | p c       = r-                        | otherwise = c- -- | Try to render meaningful time-axis labels. -- -- /FIXME/: Trouble is, we need to know the range of times for this to@@ -189,3 +187,26 @@                | t >= 1e2  = printf "%.0f %s" t u                | t >= 1e1  = printf "%.1f %s" t u                | otherwise = printf "%.2f %s" t u+#endif++writeTo :: FilePath -> (Handle -> IO a) -> IO a+writeTo path = withBinaryFile path WriteMode++escapeCSV :: String -> String+escapeCSV xs | any (`elem`xs) escapes = '"' : concatMap esc xs ++ "\""+          | otherwise              = xs+    where esc '"' = "\"\""+          esc c   = [c]+          escapes = "\"\r\n,"++putRow :: Handle -> [String] -> IO ()+putRow h s = hPutStr h (concat (intersperse "," (map escapeCSV s)) ++ "\r\n")++-- | Get rid of spaces and other potentially troublesome characters+-- from output.+mangle :: String -> FilePath+mangle = concatMap (replace ((==) '-' . head) "-")+       . group+       . map (replace isSpace '-' . replace (==pathSeparator) '-' . toLower)+    where replace p r c | p c       = r+                        | otherwise = c
README view
@@ -8,6 +8,23 @@ and take a look at the programs in the examples directory.  +Building and installing+-----------------------++To build and install criterion, just run++  cabal install criterion++On Mac OS X, the Chart library that criterion uses is not available,+so you'll have to build without it.++  cabal install criterion -f-chart+ +This will lose you the ability to generate charts, but you'll still be+able to generate CSV files and import them into your favourite+spreadsheet, or gnuplot, or whatnot.++ Get involved! ------------- 
criterion.cabal view
@@ -1,5 +1,5 @@ name:           criterion-version:        0.1+version:        0.1.2 synopsis:       Benchmarking, Performance, Testing license:        BSD3 license-file:   LICENSE@@ -9,7 +9,8 @@ category:       Development, Performance build-type:     Simple cabal-version:  >= 1.2-extra-source-files: README+extra-source-files:+  README examples/Fibber.hs examples/Judy.hs description:   This library provides a powerful but simple way to measure the   performance of Haskell code.  It provides both a framework for@@ -20,6 +21,9 @@   The fastest way to get started is to read the documentation and   examples in the Criterion.Main module. +flag Chart+  Description: enable use of the Chart package+ library   exposed-modules:     Criterion@@ -34,11 +38,9 @@     Criterion.Types    build-depends:-    Chart,     base < 5,     bytestring >= 0.9 && < 1.0,     containers,-    data-accessor,     filepath,     parallel,     parsec,@@ -46,6 +48,12 @@     time,     uvector,     uvector-algorithms >= 0.2++  if flag(chart)+    build-depends:+      Chart,+      data-accessor+    cpp-options: -DHAVE_CHART    -- gather extensive profiling data for now   ghc-prof-options: -auto-all
+ examples/Fibber.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE ScopedTypeVariables #-}++import Criterion.Main++fib :: Int -> Int+fib 0 = 0+fib 1 = 1+fib n = fib (n-1) + fib (n-2)++fact :: Int -> Integer+fact n | n < 0     = error "negative!"+       | otherwise = go (fromIntegral n)+    where go i | i == 0    = 1+               | otherwise = i * go (i-1)++fio :: Int -> IO Integer+fio n | n < 0     = error "negative!"+      | otherwise = go (fromIntegral n)+    where go i | i == 0    = return 1+               | otherwise = do+            j <- go (i-1)+            return $! i * j++main = defaultMain [+        bgroup "fib" [ bench "fib 10" $ \n -> fib (10+n-n)+                     , bench "fib 35" $ \n -> fib (35+n-n)+                     , bench "fib 37" $ \n -> fib (37+n-n)+                     ],+        bgroup "fact" [ bench "fact 100"  $ \n -> fact (100+n-n)+                      , bench "fact 1000" $ \n -> fact (1000+n-n)+                      , bench "fact 3000" $ \n -> fact (3000+n-n)+                      ],+        bgroup "fio" [ bench "fio 100"  (fio 100)+                     , bench "fio 1000" (fio 1000)+                     , bench "fio 3000" (fio 3000)+                     ]+       ]
+ examples/Judy.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE FlexibleInstances, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-full-laziness #-}++-- cabal install judy++import Control.Monad (forM_)+import Criterion.Config+import Criterion.Main+import Criterion.Types+import qualified Data.IntMap as I+import qualified Data.Judy as J+import qualified Data.Map as M+import qualified Data.IntMap as I+import Data.List (foldl')++-- Work around the fact that the GC won't run finalizers aggressively+-- enough for us.+myConfig = defaultConfig { cfgPerformGC = ljust True }++main = defaultMainWith myConfig [+        bgroup "judy" [+                     bench "insert 1M"   (testit 1000000)+                   , bench "insert 10M"  (testit 10000000)+                   , bench "insert 100M" (testit 100000000)+                   ],+        bgroup "map" [+                      bench "insert 100k" (testmap 100000)+                   , bench "insert 1M"    (testmap 1000000)+                   ],+        bgroup "intmap" [+                     bench "insert 100k" (testintmap 100000)+                   , bench "insert 1M"   (testintmap 1000000)+                   ]+    ]++testit n = do+   j <- J.new :: IO (J.JudyL Int)+   forM_ [1..n] $ \n -> J.insert n (fromIntegral n :: Int) j+   v <- J.lookup 100 j+   v `seq` return ()++testmap :: Int -> Int -> M.Map Int Int+testmap n i =+    foldl' (\m k -> M.insert k 1 m) M.empty [0..(n+i-i)]++testintmap :: Int -> Int -> I.IntMap Int+testintmap n i =+    foldl' (\m k -> I.insert k 1 m) I.empty [0..(n+i-i)]