README.md in benchmark_driver-0.1.0 vs README.md in benchmark_driver-0.2.0

- old
+ new

@@ -1,164 +1,167 @@ -# BenchmarkDriver +# BenchmarkDriver [![Build Status](https://travis-ci.org/k0kubun/benchmark_driver.svg?branch=master)](https://travis-ci.org/k0kubun/benchmark_driver) Benchmark driver for different Ruby executables ## Installation $ gem install benchmark_driver ## Usage ``` -$ benchmark_driver -h +$ exe/benchmark_driver -h Usage: benchmark_driver [options] [YAML] - -d, --duration [SECONDS] Duration seconds to run each benchmark (default: 1) -e, --executables [EXECS] Ruby executables (e1::path1; e2::path2; e3::path3;...) - -r, --result-format=FORMAT Result output format [time|ips] (default: time) + -i, --ips [SECONDS] Measure IPS in duration seconds (default: 1) + -l, --loop-count [COUNT] Measure execution time with loop count (default: 100000) -v, --verbose ``` ### Running single script -With following `bm_app_erb.yml`, +With following `example_single.yml`, ```yml prelude: | require 'erb' - - title = "hello world!" - content = "hello world!\n" * 10 - - data = <<EOS - <html> - <head> <%= title %> </head> - <body> - <h1> <%= title %> </h1> - <p> - <%= content %> - </p> - </body> - </html> - EOS - -benchmark: | - ERB.new(data).result(binding) + erb = ERB.new(%q[Hello <%= 'World' %>]) +benchmark: erb.result ``` you can benchmark the script with multiple ruby executables. ``` -$ benchmark_driver bm_app_erb.yml -e ruby1::ruby -e ruby2::ruby +$ exe/benchmark_driver ruby_benchmark_set/example_single.yml -e ruby1::ruby -e ruby2::ruby benchmark results: Execution time (sec) name ruby1 ruby2 -bm_app_erb 1.028 1.010 +example_single 0.958 0.972 Speedup ratio: compare with the result of `ruby1' (greater is better) name ruby2 -bm_app_erb 1.018 +example_single 0.986 ``` -And you can change benchmark output by `-r` option. +And you can change benchmark output to IPS (iteration per second) by `-i` option. ``` -$ benchmark_driver bm_app_erb.yml -e ruby1::ruby -e ruby2::ruby -r ips +$ exe/benchmark_driver ruby_benchmark_set/example_single.yml -e ruby1::ruby -e ruby2::ruby -i Result ------------------------------------------- ruby1 ruby2 - bm_app_erb 16082.8 i/s 15541.7 i/s + example_single 99414.1 i/s 99723.3 i/s -Comparison: bm_app_erb - ruby1: 16082.8 i/s - ruby2: 15541.7 i/s - 1.03x slower +Comparison: example_single + ruby2: 99723.3 i/s + ruby1: 99414.1 i/s - 1.00x slower ``` ### Running multiple scripts One YAML file can contain multiple benchmark scripts. -With following `erb_compile_render.yml`, +With following `example_multi.yml`, ```yml -- name: erb_compile - prelude: | - require 'erb' - - title = "hello world!" - content = "hello world!\n" * 10 - - data = <<EOS - <html> - <head> <%= title %> </head> - <body> - <h1> <%= title %> </h1> - <p> - <%= content %> - </p> - </body> - </html> - EOS - - benchmark: | - ERB.new(data).src - -- name: erb_render - prelude: | - require 'erb' - - title = "hello world!" - content = "hello world!\n" * 10 - - data = <<EOS - <html> - <head> <%= title %> </head> - <body> - <h1> <%= title %> </h1> - <p> - <%= content %> - </p> - </body> - </html> - EOS - - src = "def self.render(title, content); #{ERB.new(data).src}; end" - mod = Module.new - mod.instance_eval(src, "(ERB)") - - benchmark: | - mod.render(title, content) +prelude: | + a = 'a' * 100 + b = 'b' * 100 +benchmarks: + - name: join + benchmark: | + [a, b].join + - name: interpolation + benchmark: | + "#{a}#{b}" ``` you can benchmark the scripts with multiple ruby executables. ``` -$ benchmark_driver erb_compile_render.yml -e ruby1::ruby -e ruby2::ruby +$ exe/benchmark_driver ruby_benchmark_set/example_multi.yml -e ruby1::ruby -e ruby2::ruby benchmark results: Execution time (sec) name ruby1 ruby2 -erb_compile 0.987 0.985 -erb_render 0.834 0.809 +join 0.022 0.022 +interpolation 0.026 0.026 Speedup ratio: compare with the result of `ruby1' (greater is better) name ruby2 -erb_compile 1.002 -erb_render 1.031 +join 1.045 +interpolation 1.002 ``` ``` -$ benchmark_driver erb_compile_render.yml -e ruby1::ruby -e ruby2::ruby -r ips +$ exe/benchmark_driver ruby_benchmark_set/example_multi.yml -e ruby1::ruby -e ruby2::ruby -i Result ------------------------------------------- ruby1 ruby2 - erb_compile 30374.0 i/s 30832.1 i/s - erb_render 628403.5 i/s 624588.0 i/s + join 4701954.3 i/s 4639520.3 i/s + interpolation 4263170.0 i/s 4044083.0 i/s -Comparison: erb_compile - ruby2: 30832.1 i/s - ruby1: 30374.0 i/s - 1.02x slower +Comparison: join + ruby1: 4701954.3 i/s + ruby2: 4639520.3 i/s - 1.01x slower -Comparison: erb_render - ruby1: 628403.5 i/s - ruby2: 624588.0 i/s - 1.01x slower +Comparison: interpolation + ruby1: 4263170.0 i/s + ruby2: 4044083.0 i/s - 1.05x slower ``` +### Configuring modes + +There are 2 modes: + +- Loop count: Enabled by `-l`. Optionally you can change count to loop by `-l COUNT`. +- IPS: Enabled by `-i`. Optionally you can change duration by `-i DURATION`. + +Specifying both `-l` and `-i` is nonsense. + +### YAML syntax +You can specify `benchmark:` or `benchmarks:`. + +#### Single +```yml +name: String # optional (default: file name) +prelude: String # optional +loop_count: Integer # optional +benchmark: String # required +``` + +#### Multi + +```yml +prelude: String # optional (shared) +loop_count: Integer # optional (shared) +benchmarks: + - name: String # required + prelude: String # optional (benchmark specific) + loop_count: Integer # optional (benchmark specific) + benchmark: String # required +``` + +### Debugging + +If you have a trouble like an unexpectedly fast result, you should check benchmark script by `-v`. + +``` +$ exe/benchmark_driver ruby_benchmark_set/example_multi.yml -v +--- Running "join" with "ruby" 957780 times --- +a = 'a' * 100 +b = 'b' * 100 + + +i = 0 +while i < 957780 + i += 1 +[a, b].join + +end +``` + +## TODO + +- Measure multiple times and use minimum result +- Retry and reject negative result in ips mode +- Change not to take long time for iteration count estimation in ips mode ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/k0kubun/benchmark_driver.