A common Ruby idiom for variadic methods is to flatten the argument
list so that it can be called with either variadic arguments or an
Array.
e.g. from the sqlite3 gem:
```ruby
def bind_params(*bind_vars)
bind_vars.flatten.each do |var|
# ...
```
However, as soon as `flatten` encounter another array, it has to
protect against recursion, which requires allocating an expensive
identity Hash.
So this pattern has a relatively high cost when called with
a single array argument (e.g. `bind_params [1, 2, 3]`).
We can specialize for that common case without noticeably
impacting other usages of `Array#flatten`:
| |compare-ruby|built-ruby|
|:-----------------------------|-----------:|---------:|
|small_flat_ary.flatten | 7.547M| 7.974M|
| | -| 1.06x|
|small_flat_ary.flatten! | 6.031M| 6.105M|
| | -| 1.01x|
|large_flat_ary.flatten | 465.896k| 485.861k|
| | -| 1.04x|
|large_flat_ary.flatten! | 455.872k| 478.103k|
| | -| 1.05x|
|small_pairs_ary.flatten | 1.327M| 1.407M|
| | -| 1.06x|
|small_pairs_ary.flatten! | 1.165M| 1.153M|
| | 1.01x| -|
|large_pairs_ary.flatten | 96.612k| 96.976k|
| | -| 1.00x|
|large_pairs_ary.flatten! | 94.108k| 97.289k|
| | -| 1.03x|
|mostly_flat_ary.flatten | 399.648k| 417.327k|
| | -| 1.04x|
|mostly_flat_ary.flatten! | 378.315k| 395.946k|
| | -| 1.05x|
|small_nested_ary.flatten | 2.513M| 7.788M|
| | -| 3.10x|
|small_nested_ary.flatten! | 2.024M| 5.914M|
| | -| 2.92x|
|large_nested_ary.flatten | 341.635k| 485.319k|
| | -| 1.42x|
|large_nested_ary.flatten! | 329.837k| 475.014k|
| | -| 1.44x|
|small_nested_ary.flatten(1) | 9.497M| 61.350M|
| | -| 6.46x|
|small_nested_ary.flatten!(1) | 5.136M| 17.668M|
| | -| 3.44x|
|large_nested_ary.flatten(1) | 1.575M| 60.241M|
| | -| 38.26x|
|large_nested_ary.flatten!(1) | 1.369M| 16.835M|
| | -| 12.30x|
Execute gem install benchmark_driver and run a command like:
# Run a benchmark script with the ruby in the $PATH
benchmark-driver benchmark/app_fib.rb
# Run benchmark scripts with multiple Ruby executables or options
benchmark-driver benchmark/*.rb -e /path/to/ruby -e '/path/to/ruby --jit'# Or compare Ruby versions managed by rbenv
benchmark-driver benchmark/*.rb --rbenv '2.5.1;2.6.0-preview2 --jit'# You can collect many metrics in many ways
benchmark-driver benchmark/*.rb --runner memory --output markdown
# Some are defined with YAML for complex setup or accurate measurement
benchmark-driver benchmark/*.yml
See also:
benchmark-driver --help
Usage: benchmark-driver [options] RUBY|YAML...
-r, --runner TYPE Specify runner type: ips, time, memory, once, block (default: ips)
-o, --output TYPE Specify output type: compare, simple, markdown, record, all (default: compare)
-e, --executables EXECS Ruby executables (e1::path1 arg1; e2::path2 arg2;...)
--rbenv VERSIONS Ruby executables in rbenv (x.x.x arg1;y.y.y arg2;...)
--repeat-count NUM Try benchmark NUM times and use the fastest result or the worst memory usage
--repeat-result TYPE Yield "best", "average" or "worst" result with --repeat-count (default: best)
--alternate Alternate executables instead of running the same executable in a row with --repeat-count
--bundler Install and use gems specified in Gemfile
--filter REGEXP Filter out benchmarks with given regexp
--run-duration SECONDS Warmup estimates loop_count to run for this duration (default: 3)
--timeout SECONDS Timeout ruby command execution with timeout(1)
-v, --verbose Verbose mode. Multiple -v options increase visibility (max: 2)
make benchmark
Using make benchmark, make update-benchmark-driver automatically downloads
the supported version of benchmark_driver, and it runs benchmarks with the downloaded
benchmark_driver.
# Run all benchmarks with the ruby in the $PATH and the built ruby
make benchmark
# Or compare with specific ruby binary
make benchmark COMPARE_RUBY="/path/to/ruby --jit"# Run vm benchmarks
make benchmark ITEM=vm
# Run some limited benchmarks in ITEM-matched files
make benchmark ITEM=vm OPTS=--filter=block
# You can specify the benchmark by exact filenames instead of matching ITEM:
make benchmark ARGS=benchmark/erb_render.yml
# You can specify any option via $OPTS
make benchmark OPTS="--help"# With `make benchmark`, some special runner plugins are available:# -r peak, -r size, -r total, -r utime, -r stime, -r cutime, -r cstime
make benchmark ITEM=vm_bigarray OPTS="-r peak"