Stack のbenchmarkとtest

# Stack build

Stackのbuild オプションの説明は [stack Guide](https://github.com/commercialhaskell/stack/blob/master/doc/GUIDE.md#the-build-command)にあるが、あまり詳しくない。

簡単に言うと、.cabal ファイルに

```haskell
benchmark hohe-bench1
  type:                exitcode-stdio-1.0
  hs-source-dirs:      models
  build-depends:       base
                     , monad-bayes
                     , ...
  default-language:    Haskell2010
  main-is:             BenchAll.hs
  other-modules:       Sprinkler,
                       ...

```

のような、benchmark宣言されたもの(その実行用mainを持つファイルは、dir = "models"の"BenchAll.hs"というファイルであると書いてある)と、以下のような別のbenchmark宣言したもの("BenchPart.hs"がmainを持つ)とがあるときに、このbenchmark宣言を見て、benchmarkたちをコンパイルして実行する。

```haskell
benchmark hohe-bench2
  type:                exitcode-stdio-1.0
  hs-source-dirs:      models
  build-depends:       base
                     , monad-bayes
                     , ...
  default-language:    Haskell2010
  main-is:             BenchPart.hs
  other-modules:       Sprinkler,
                       ...
```

両方をコンパイルする。

コンパイル実行コマンドは

```bash
stack build --bench
```

その後、(再度)実行するには

```bash
stack bench
```

# 例

[昨日の記事](http://qiita.com/ryamada22/items/2a146e99e94aaff79bc4)で使用した

monad-bayes パッケージの場合、ローカルに取ってきたパッケージのディレクトリのmonad-bayes.cabalファイルには以下の３つのbenchmarkが記載されているので

```haskell
benchmark monad-bayes-bench
benchmark nonlinear-benchmark
benchmark lgss-benchmark
```

```bash
stack --bench
```

すると、末尾に示すように、どあーっとbuildに伴う処理経過が出るが、末尾に

```
Registering monad-bayes-0.1.0.0...
monad-bayes-0.1.0.0: benchmarks
Running 3 benchmarks...
Benchmark lgss-benchmark: RUNNING...
running LGSS benchmark
Benchmark lgss-benchmark: FINISH
Benchmark monad-bayes-bench: RUNNING...
running HMM benchmark
Benchmark monad-bayes-bench: FINISH
Benchmark nonlinear-benchmark: RUNNING...
running Nonlinear benchmark
Benchmark nonlinear-benchmark: FINISH
Completed 37 action(s).
```

とあるように、３つのbenchmarkがコンパイルの後、実行して終了していること。

ここでコンパイルが済んでいるので、この後、再度 stack buildすると、benchmarkだけが実行されるのは、以下で解る。

```
ryamada@ryamada-CFSX4-1:~/デスクトップ/gitclone/monad-bayes$ stack bench
monad-bayes-0.1.0.0: benchmarks
Registering monad-bayes-0.1.0.0...
monad-bayes-0.1.0.0: benchmarks
Running 3 benchmarks...
Benchmark lgss-benchmark: RUNNING...
running LGSS benchmark
Benchmark lgss-benchmark: FINISH
Benchmark monad-bayes-bench: RUNNING...
running HMM benchmark
Benchmark monad-bayes-bench: FINISH
Benchmark nonlinear-benchmark: RUNNING...
running Nonlinear benchmark
Benchmark nonlinear-benchmark: FINISH
Completed 37 action(s).
```

build --bench 時の標準出力は以下。

```
ryamada@ryamada-CFSX4-1:~/デスクトップ/gitclone/monad-bayes$ stack build --benchmonad-bayes-0.1.0.0: unregistering (missing dependencies: Chart, Chart-cairo, optparse-applicative, statistics)
ansi-terminal-0.6.2.3: configure
ansi-terminal-0.6.2.3: build
adjunctions-4.3: configure
adjunctions-4.3: build
abstract-deque-0.3: download
abstract-par-0.3.3: download
abstract-par-0.3.3: configure
abstract-par-0.3.3: build
abstract-deque-0.3: configure
abstract-deque-0.3: build
abstract-par-0.3.3: copy/register
abstract-deque-0.3: copy/register
cereal-0.5.3.0: download
ansi-terminal-0.6.2.3: copy/register
ansi-wl-pprint-0.6.7.3: configure
ansi-wl-pprint-0.6.7.3: build
cereal-0.5.3.0: configure
colour-2.3.3: download
cereal-0.5.3.0: build
colour-2.3.3: configure
adjunctions-4.3: copy/register
colour-2.3.3: build
ansi-wl-pprint-0.6.7.3: copy/register
data-default-class-0.1.2.0: download
data-default-class-0.1.2.0: configure
data-default-class-0.1.2.0: build
dlist-0.8.0.2: download
dlist-0.8.0.2: configure
dlist-0.8.0.2: build
data-default-class-0.1.2.0: copy/register
fail-4.9.0.0: configure
fail-4.9.0.0: build
fail-4.9.0.0: copy/register
dlist-0.8.0.2: copy/register
happy-1.19.5: download
hashtables-1.2.1.0: download
happy-1.19.5: configure
colour-2.3.3: copy/register
kan-extensions-5.0.1: download
happy-1.19.5: build
hashtables-1.2.1.0: configure
hashtables-1.2.1.0: build
kan-extensions-5.0.1: configure
kan-extensions-5.0.1: build
cereal-0.5.3.0: copy/register
monad-par-extras-0.3.3: download
monad-par-extras-0.3.3: configure
monad-par-extras-0.3.3: build
kan-extensions-5.0.1: copy/register
old-locale-1.0.0.7: configure
old-locale-1.0.0.7: build
monad-par-extras-0.3.3: copy/register
old-locale-1.0.0.7: copy/register
monad-par-0.3.4.8: download
monad-par-0.3.4.8: configure
operational-0.2.3.4: download
monad-par-0.3.4.8: build
operational-0.2.3.4: configure
operational-0.2.3.4: build
hashtables-1.2.1.0: copy/register
operational-0.2.3.4: copy/register
optparse-applicative-0.12.1.0: download
optparse-applicative-0.12.1.0: configure
optparse-applicative-0.12.1.0: build
scientific-0.3.4.9: configure
scientific-0.3.4.9: build
monad-par-0.3.4.8: copy/register
syb-0.6: configure
syb-0.6: build 
happy-1.19.5: copy/register
tf-random-0.5: configure
tf-random-0.5: build
syb-0.6: copy/register
unordered-containers-0.2.7.1: configure
unordered-containers-0.2.7.1: build
tf-random-0.5: copy/register
QuickCheck-2.8.2: configure
QuickCheck-2.8.2: build
scientific-0.3.4.9: copy/register
optparse-applicative-0.12.1.0: copy/register
attoparsec-0.13.1.0: configure
attoparsec-0.13.1.0: build
utf8-string-1.0.1.1: configure
utf8-string-1.0.1.1: build
utf8-string-1.0.1.1: copy/register
vector-algorithms-0.7.0.1: configure
vector-algorithms-0.7.0.1: build
QuickCheck-2.8.2: copy/register
alex-3.1.7: download
alex-3.1.7: configure
Package alex uses a custom Cabal build, but does not use a custom-setup stanza
Not using the explicit setup deps approach based on configuration
Strongly recommend fixing the package's cabal file
unordered-containers-0.2.7.1: copy/register
lens-4.14: download
alex-3.1.7: build
Package alex uses a custom Cabal build, but does not use a custom-setup stanza
Not using the explicit setup deps approach based on configuration
Strongly recommend fixing the package's cabal file
lens-4.14: configure
Package lens uses a custom Cabal build, but does not use a custom-setup stanza
Not using the explicit setup deps approach based on configuration
Strongly recommend fixing the package's cabal file
lens-4.14: build
Package lens uses a custom Cabal build, but does not use a custom-setup stanza
Not using the explicit setup deps approach based on configuration
Strongly recommend fixing the package's cabal file
alex-3.1.7: copy/register
Package alex uses a custom Cabal build, but does not use a custom-setup stanza
Not using the explicit setup deps approach based on configuration
Strongly recommend fixing the package's cabal file
gtk2hs-buildtools-0.13.2.1: download
gtk2hs-buildtools-0.13.2.1: configure
gtk2hs-buildtools-0.13.2.1: build
attoparsec-0.13.1.0: copy/register
aeson-0.11.2.1: download
aeson-0.11.2.1: configure
aeson-0.11.2.1: build
vector-algorithms-0.7.0.1: copy/register
vector-binary-instances-0.2.3.2: configure
vector-binary-instances-0.2.3.2: build
vector-binary-instances-0.2.3.2: copy/register
gtk2hs-buildtools-0.13.2.1: copy/register
cairo-0.13.3.1: download
cairo-0.13.3.1: configure
cairo-0.13.3.1: build
aeson-0.11.2.1: copy/register
statistics-0.13.3.0: download
statistics-0.13.3.0: configure
statistics-0.13.3.0: build
lens-4.14: copy/register
Package lens uses a custom Cabal build, but does not use a custom-setup stanza
Not using the explicit setup deps approach based on configuration
Strongly recommend fixing the package's cabal file
Package lens uses a custom Cabal build, but does not use a custom-setup stanza
Not using the explicit setup deps approach based on configuration
Strongly recommend fixing the package's cabal file
Chart-1.8.1: download
Chart-1.8.1: configure
cairo-0.13.3.1: copy/register
Chart-1.8.1: build
Chart-1.8.1: copy/register
Chart-cairo-1.8.1: download
Chart-cairo-1.8.1: configure
Chart-cairo-1.8.1: build
Chart-cairo-1.8.1: copy/register
statistics-0.13.3.0: copy/register
monad-bayes-0.1.0.0: configure (lib + bench)
Configuring monad-bayes-0.1.0.0...
monad-bayes-0.1.0.0: build (lib + bench)
Preprocessing library monad-bayes-0.1.0.0...
Preprocessing benchmark 'lgss-benchmark' for monad-bayes-0.1.0.0...
[1 of 2] Compiling Plotting         ( models/Plotting.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/lgss-benchmark/lgss-benchmark-tmp/Plotting.o )
[2 of 2] Compiling Main             ( models/LGSS.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/lgss-benchmark/lgss-benchmark-tmp/Main.o )
Linking .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/lgss-benchmark/lgss-benchmark ...
Preprocessing benchmark 'monad-bayes-bench' for monad-bayes-0.1.0.0...
[1 of 7] Compiling Plotting         ( models/Plotting.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench-tmp/Plotting.o )
[2 of 7] Compiling HMM              ( models/HMM.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench-tmp/HMM.o )
[3 of 7] Compiling Gamma            ( models/Gamma.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench-tmp/Gamma.o )
[4 of 7] Compiling DPmixture        ( models/DPmixture.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench-tmp/DPmixture.o )
[5 of 7] Compiling Dice             ( models/Dice.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench-tmp/Dice.o )
[6 of 7] Compiling BetaBin          ( models/BetaBin.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench-tmp/BetaBin.o )
[7 of 7] Compiling Main             ( models/BenchAll.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench-tmp/Main.o )
Linking .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/monad-bayes-bench/monad-bayes-bench ...
Preprocessing benchmark 'nonlinear-benchmark' for monad-bayes-0.1.0.0...
[1 of 2] Compiling Plotting         ( models/Plotting.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/nonlinear-benchmark/nonlinear-benchmark-tmp/Plotting.o )
[2 of 2] Compiling Main             ( models/Nonlinear.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/nonlinear-benchmark/nonlinear-benchmark-tmp/Main.o )
Linking .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/nonlinear-benchmark/nonlinear-benchmark ...
monad-bayes-0.1.0.0: copy/register
Installing library in
/home/ryamada/デスクトップ/gitclone/monad-bayes/.stack-work/install/x86_64-linux/lts-7.7/8.0.1/lib/x86_64-linux-ghc-8.0.1/monad-bayes-0.1.0.0-KuBj2n246oHCR7lgdHP4WX
Registering monad-bayes-0.1.0.0...
monad-bayes-0.1.0.0: benchmarks
Running 3 benchmarks...
Benchmark lgss-benchmark: RUNNING...
running LGSS benchmark
Benchmark lgss-benchmark: FINISH
Benchmark monad-bayes-bench: RUNNING...
running HMM benchmark
Benchmark monad-bayes-bench: FINISH
Benchmark nonlinear-benchmark: RUNNING...
running Nonlinear benchmark
Benchmark nonlinear-benchmark: FINISH
Completed 37 action(s).
```

# stack --test

testオプションのほうもbuild オプションと同様に、test宣言されている項目がコンパイルされて実行されるはず。

実際には、Test.Hspecなるモジュールの hspecという関数を使う。

マニュアルは[こちら](http://hspec.github.io/)