packages feed

bench 1.0.1 → 1.0.2

raw patch · 3 files changed

+106/−34 lines, 3 filesdep +optparse-applicative

Dependencies added: optparse-applicative

Files

README.md view
@@ -1,7 +1,8 @@-# Bench v1.0.1+# Bench v1.0.2 -Think of this as a more powerful alternative to the `time` command.  Use this-command-line tool to benchmark a command using Haskell's `criterion` library.+This project provides the `bench` command-line tool, which is a more powerful+alternative to the `time` command.  Use `bench` to benchmark a command using+Haskell's `criterion` library.  Key features: @@ -13,27 +14,26 @@  ## Quick Start -First, download the-[Haskell toolchain](https://www.haskell.org/downloads#minimal), which provides-the `stack` build tool.+You can download a pre-built binary for OS X on the releases page: -You will also need to download [git](https://git-scm.com/downloads) if you-haven't done so already.+* https://github.com/Gabriel439/bench/releases -Then run the following commands from a terminal to build and install the `bench`-tool:+... or you can install `bench` using Haskell's `stack` tool.  To do that, first+download the [Haskell toolchain](https://www.haskell.org/downloads#minimal),+which provides the `stack` tool, then run:  ```bash-$ git clone https://github.com/Gabriel439/bench.git-$ cd bench-$ stack install+$ stack setup+$ stack install bench ```  `stack install` will install `bench` to `~/.local/bin` or something similar. Make sure that the installation directory is on your executable search path-before running the following command.  `stack` will remind you to do this if you-forget.+before running `bench`.  `stack` will remind you to do this if you forget. +Once you've installed `bench` (either by download or installation via `stack`),+you can begin benchmarking programs:+ ```bash $ bench 'sleep 1'  # Don't forget to quote the command line benchmarking sleep 1@@ -52,7 +52,49 @@ variance introduced by outliers: 81% (severely inflated) ``` -All output from the command being benchmarked is discarded+All output from the command being benchmarked is discarded.++Multiple commands are also supported:++```bash+$ bench id ls "sleep 0.1"+benchmarking bench/id+time                 4.798 ms   (4.764 ms .. 4.833 ms)+                     0.999 R²   (0.998 R² .. 1.000 R²)+mean                 4.909 ms   (4.879 ms .. 4.953 ms)+std dev              104.6 μs   (78.91 μs .. 135.7 μs)++benchmarking bench/ls+time                 2.941 ms   (2.889 ms .. 3.006 ms)+                     0.996 R²   (0.992 R² .. 0.998 R²)+mean                 3.051 ms   (3.015 ms .. 3.094 ms)+std dev              129.7 μs   (104.3 μs .. 178.3 μs)+variance introduced by outliers: 25% (moderately inflated)++benchmarking bench/sleep 0.1+time                 109.9 ms   (108.5 ms .. 111.0 ms)+                     1.000 R²   (1.000 R² .. 1.000 R²)+mean                 109.2 ms   (108.5 ms .. 109.7 ms)+std dev              903.0 μs   (676.4 μs .. 1.212 ms)+```++You can also output an HTML file graphing the distribution of+timings by using the `--output` flag:++```bash+$ bench 'ls /usr/bin | wc -l' --output example.html+benchmarking ls /usr/bin | wc -l+time                 6.716 ms   (6.645 ms .. 6.807 ms)+                     0.999 R²   (0.999 R² .. 0.999 R²)+mean                 7.005 ms   (6.897 ms .. 7.251 ms)+std dev              462.0 μs   (199.3 μs .. 809.2 μs)+variance introduced by outliers: 37% (moderately inflated)+```++... and if you open that page in your browser you will+get something that looks like this:++![](http://i.imgur.com/2MCKBc2.png)  ## Usage 
bench.cabal view
@@ -1,5 +1,5 @@ name:                bench-version:             1.0.1+version:             1.0.2 synopsis:            Command-line benchmark tool description:         Think of this as a more powerful alternative to the @time@                      command.  Use this command-line tool to benchmark a command@@ -25,9 +25,10 @@   hs-source-dirs:      src   main-is:             Main.hs   default-language:    Haskell2010-  build-depends:       base      >= 4.5     && < 5-                     , criterion >= 1.1.1.0 && < 1.2-                     , text                    < 1.3-                     , silently  >= 1.1.1   && < 1.3-                     , turtle    >= 1.2.5   && < 1.3+  build-depends:       base                 >= 4.5     && < 5+                     , criterion            >= 1.1.1.0 && < 1.2+                     , optparse-applicative >= 0.2.0   && < 0.14+                     , silently             >= 1.1.1   && < 1.3+                     , text                               < 1.3+                     , turtle               >= 1.2.5   && < 1.3   ghc-options:         -Wall -O2 -threaded
src/Main.hs view
@@ -1,34 +1,63 @@ {-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RecordWildCards    #-}  module Main where  import Control.Applicative+import Data.Monoid ((<>)) import Data.Text (Text)-import Turtle (Parser)+import Turtle (Parser, s, (%))  import qualified Criterion import qualified Criterion.Main         as Criterion import qualified Criterion.Main.Options as Criterion import qualified Data.Text              as Text+import qualified Options.Applicative import qualified System.IO              as IO import qualified System.IO.Silently     as Silently import qualified Turtle -data Options = Options-    { command   :: Text-    , mode      :: Criterion.Mode-    }+version :: Text+version = "1.0.2" +data Options = Options [Text] Criterion.Mode | Version deriving (Show)+ parser :: Parser Options parser =-        Options-    <$> Turtle.argText "command" "The command line to benchmark"-    <*> Criterion.parseWith Criterion.defaultConfig+            Version+        <$  Options.Applicative.flag'+                ()+                (   Options.Applicative.short 'v'+                <>  Options.Applicative.long "version"+                <>  Options.Applicative.help "Version number"+                )+    <|>     Options+        <$> some+                (Turtle.argText "command(s)" "The command line(s) to benchmark")+        <*> Criterion.parseWith Criterion.defaultConfig  main :: IO () main = do-    o <- Turtle.options "Command-line tool to benchmark other programs" parser-    let io        = Turtle.shells (command o) empty+    x <- Turtle.options "Command-line tool to benchmark other programs" parser+    case x of+        Options [command] mode -> benchCommand  command mode+        Options  commands mode -> benchCommands commands mode+        Version -> do+            Turtle.printf ("bench version "%s%"\n") version++benchCommands :: [Text] -> Criterion.Mode -> IO ()+benchCommands commands mode = do+    let benches = map buildBench commands+    Criterion.runMode mode [Criterion.bgroup "bench" benches]++benchCommand :: Text -> Criterion.Mode -> IO ()+benchCommand command mode = do+    let bench = buildBench command+    Criterion.runMode mode [ bench ]++buildBench :: Text -> Criterion.Benchmark+buildBench command = do+    let io        = Turtle.shells command empty     let benchmark = Criterion.nfIO (Silently.hSilence [IO.stdout, IO.stderr] io)-    let name      = Text.unpack (command o)-    Criterion.runMode (mode o) [ Criterion.bench name benchmark ]+    let bench     = Criterion.bench (Text.unpack command) benchmark+    bench