diff options
Diffstat (limited to 'benchmark')
435 files changed, 5746 insertions, 1527 deletions
diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 0000000000..9f9192685e --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,75 @@ +# ruby/benchmark + +This directory has benchmark definitions to be run with +[benchmark\_driver.gem](https://github.com/benchmark-driver/benchmark-driver). + +## Normal usage + +Execute `gem install benchmark_driver` and run a command like: + +```bash +# 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: + +```console +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. + +```bash +# 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 an exact filename instead of using the default argument: +# ARGS = $$(find $(srcdir)/benchmark -maxdepth 1 -name '*$(ITEM)*.yml' -o -name '*$(ITEM)*.rb') +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" +``` diff --git a/benchmark/bm_app_answer.rb b/benchmark/app_answer.rb index 3cd8a8fd37..3cd8a8fd37 100644 --- a/benchmark/bm_app_answer.rb +++ b/benchmark/app_answer.rb diff --git a/benchmark/bm_app_aobench.rb b/benchmark/app_aobench.rb index 807349089f..c1546e08ab 100644 --- a/benchmark/bm_app_aobench.rb +++ b/benchmark/app_aobench.rb @@ -1,7 +1,8 @@ -# AO rebder benchmark +# coding: US-ASCII + +# AO render benchmark # Original program (C) Syoyo Fujita in Javascript (and other languages) -# http://lucille.atso-net.jp/blog/?p=642 -# http://lucille.atso-net.jp/blog/?p=711 +# https://code.google.com/p/aobench/ # Ruby(yarv2llvm) version by Hideki Miura # @@ -10,6 +11,8 @@ IMAGE_HEIGHT = 256 NSUBSAMPLES = 2 NAO_SAMPLES = 8 +srand(0) + class Vec def initialize(x, y, z) @x = x @@ -148,7 +151,7 @@ def clamp(f) i.to_i end -def otherBasis(basis, n) +def orthoBasis(basis, n) basis[2] = Vec.new(n.x, n.y, n.z) basis[1] = Vec.new(0.0, 0.0, 0.0) @@ -180,7 +183,7 @@ class Scene def ambient_occlusion(isect) basis = Array.new - otherBasis(basis, isect.n) + orthoBasis(basis, isect.n) ntheta = NAO_SAMPLES nphi = NAO_SAMPLES @@ -230,7 +233,7 @@ class Scene w.times do |x| rad = Vec.new(0.0, 0.0, 0.0) - # Subsmpling + # Subsampling nsubsamples.times do |v| nsubsamples.times do |u| @@ -279,12 +282,14 @@ end alias printf_orig printf def printf *args + # $fp.printf(*args) end # File.open("ao.ppm", "w") do |fp| + # $fp = fp printf("P6\n") printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT) - printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT) + printf("255\n") Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES) # end diff --git a/benchmark/app_erb.yml b/benchmark/app_erb.yml new file mode 100644 index 0000000000..31e29b7644 --- /dev/null +++ b/benchmark/app_erb.yml @@ -0,0 +1,23 @@ +# +# Create many HTML strings with ERB. +# +prelude: | + require 'erb' + + data = <<erb + <html> + <head> <%= title %> </head> + <body> + <h1> <%= title %> </h1> + <p> + <%= content %> + </p> + </body> + </html> + erb + + title = "hello world!" + content = "hello world!\n" * 10 +benchmark: + app_erb: ERB.new(data).result(binding) +loop_count: 15000 diff --git a/benchmark/bm_app_factorial.rb b/benchmark/app_factorial.rb index 45f471dfdb..45f471dfdb 100644 --- a/benchmark/bm_app_factorial.rb +++ b/benchmark/app_factorial.rb diff --git a/benchmark/bm_app_fib.rb b/benchmark/app_fib.rb index 34a7b2e725..e61bc8aa32 100644 --- a/benchmark/bm_app_fib.rb +++ b/benchmark/app_fib.rb @@ -1,4 +1,4 @@ -def fib n +def fib(n) if n < 3 1 else diff --git a/benchmark/app_lc_fizzbuzz.rb b/benchmark/app_lc_fizzbuzz.rb new file mode 100644 index 0000000000..f09574bbeb --- /dev/null +++ b/benchmark/app_lc_fizzbuzz.rb @@ -0,0 +1,52 @@ +# +# FizzBuzz program using only lambda calculus +# +# This program is quoted from +# "Understanding Computation" by Tom Stuart +# http://computationbook.com/ +# +# You can understand why this program works fine by reading this book. +# + +solution = -> k { -> f { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][k][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> l { -> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[l][f[x]] } }] } }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[m][n]][-> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[f[-> n { -> p { -> x { p[n[p][x]] } } }[m]][n]][m][x] }][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]] } } }][-> p { -> x { p[x] } }][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] } }]][-> n { -> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[x]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> n { -> l { -> x { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][l][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][x]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }] } }[-> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> x { f[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { -> n { -> p { -> x { p[n[p][x]] } } }[f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n]][x] }][-> p { -> x { x } }] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][x] }]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]] } }][n]]]] }] + +FIRST = -> l { LEFT[RIGHT[l]] } +IF = -> b { b } +LEFT = -> p { p[-> x { -> y { x } } ] } +RIGHT = -> p { p[-> x { -> y { y } } ] } +IS_EMPTY = LEFT +REST = -> l { RIGHT[RIGHT[l]] } + +def to_integer(proc) + proc[-> n { n + 1 }][0] +end + +def to_boolean(proc) + IF[proc][true][false] +end + +def to_array(proc) + array = [] + + until to_boolean(IS_EMPTY[proc]) + array.push(FIRST[proc]) + proc = REST[proc] + end + + array +end + +def to_char(c) + '0123456789BFiuz'.slice(to_integer(c)) +end + +def to_string(s) + to_array(s).map { |c| to_char(c) }.join +end + +answer = to_array(solution).map do |p| + to_string(p) +end + +answer_ary = answer.to_a +# puts answer_ary diff --git a/benchmark/bm_app_mandelbrot.rb b/benchmark/app_mandelbrot.rb index 801b75e8e2..801b75e8e2 100644 --- a/benchmark/bm_app_mandelbrot.rb +++ b/benchmark/app_mandelbrot.rb diff --git a/benchmark/bm_app_pentomino.rb b/benchmark/app_pentomino.rb index 59c63f358e..47be7b203f 100644 --- a/benchmark/bm_app_pentomino.rb +++ b/benchmark/app_pentomino.rb @@ -128,132 +128,3 @@ mkboard $p[4] = [$p[4][0]] $pnum = (0...$p.length).to_a setpiece([],0) - - -__END__ - -# original - -NP = 5 -ROW = 8 + NP -COL = 8 - -$p = [] -$b = [] -$no = 0 - -def piece(n,a,nb) - for x in nb - a[n] = x - if n == NP-1 - $p << [a.sort] - else - nbc=nb.dup - for d in [-ROW, -1, 1, ROW] - if x+d > 0 and not a.include?(x+d) and not nbc.include?(x+d) - nbc << x+d - end - end - nbc.delete x - piece(n+1,a[0..n],nbc) - end - end -end - -def kikaku(a) - a.collect {|x| x - a[0]} -end -def ud(a) - kikaku(a.collect {|x| ((x+NP)%ROW)-ROW*((x+NP)/ROW) }.sort) -end -def rl(a) - kikaku(a.collect {|x| ROW*((x+NP)/ROW)+ROW-((x+NP)%ROW)}.sort) -end -def xy(a) - kikaku(a.collect {|x| ROW*((x+NP)%ROW) + (x+NP)/ROW }.sort) -end - -def mkpieces - piece(0,[],[0]) - $p.each do |a| - a0 = a[0] - a[1] = ud(a0) - a[2] = rl(a0) - a[3] = ud(rl(a0)) - a[4] = xy(a0) - a[5] = ud(xy(a0)) - a[6] = rl(xy(a0)) - a[7] = ud(rl(xy(a0))) - a.sort! - a.uniq! - end - $p.uniq!.sort! {|x,y| x[0] <=> y[0] } -end - -def mkboard - for i in 0...ROW*COL - if i % ROW >= ROW-NP - $b[i] = -2 - else - $b[i] = -1 - end - $b[3*ROW+3]=$b[3*ROW+4]=$b[4*ROW+3]=$b[4*ROW+4]=-2 - end -end - -def pboard - print "No. #$no\n" - for i in 0...COL - print "|" - for j in 0...ROW-NP - x = $b[i*ROW+j] - if x < 0 - print "..|" - else - printf "%2d|",x+1 - end - end - print "\n" - end - print "\n" -end - -$pnum=[] -def setpiece(a,pos) - if a.length == $p.length then - $no += 1 - pboard - return - end - while $b[pos] != -1 - pos += 1 - end - ($pnum - a).each do |i| - $p[i].each do |x| - f = 0 - for s in x do - if $b[pos+s] != -1 - f=1 - break - end - end - if f == 0 then - for s in x do - $b[pos+s] = i - end - a << i - setpiece(a.dup, pos) - a.pop - for s in x do - $b[pos+s] = -1 - end - end - end - end -end - -mkpieces -mkboard -$p[4] = [$p[4][0]] -$pnum = (0...$p.length).to_a -setpiece([],0) diff --git a/benchmark/bm_app_raise.rb b/benchmark/app_raise.rb index 5db8f95d50..5db8f95d50 100644 --- a/benchmark/bm_app_raise.rb +++ b/benchmark/app_raise.rb diff --git a/benchmark/bm_app_strconcat.rb b/benchmark/app_strconcat.rb index 7eed7c1aed..7eed7c1aed 100644 --- a/benchmark/bm_app_strconcat.rb +++ b/benchmark/app_strconcat.rb diff --git a/benchmark/bm_app_tak.rb b/benchmark/app_tak.rb index efe5380f4e..efe5380f4e 100644 --- a/benchmark/bm_app_tak.rb +++ b/benchmark/app_tak.rb diff --git a/benchmark/bm_app_tarai.rb b/benchmark/app_tarai.rb index 4c146f5ccf..4c146f5ccf 100644 --- a/benchmark/bm_app_tarai.rb +++ b/benchmark/app_tarai.rb diff --git a/benchmark/bm_app_uri.rb b/benchmark/app_uri.rb index 586edfd5dc..586edfd5dc 100644 --- a/benchmark/bm_app_uri.rb +++ b/benchmark/app_uri.rb diff --git a/benchmark/array_flatten.yml b/benchmark/array_flatten.yml new file mode 100644 index 0000000000..88ef544ba0 --- /dev/null +++ b/benchmark/array_flatten.yml @@ -0,0 +1,19 @@ +prelude: | + small_flat_ary = 5.times.to_a + large_flat_ary = 100.times.to_a + small_pairs_ary = [[1, 2]] * 5 + large_pairs_ary = [[1, 2]] * 100 + mostly_flat_ary = 100.times.to_a.push([101, 102]) + +benchmark: + small_flat_ary.flatten: small_flat_ary.flatten + small_flat_ary.flatten!: small_flat_ary.flatten! + large_flat_ary.flatten: large_flat_ary.flatten + large_flat_ary.flatten!: large_flat_ary.flatten! + small_pairs_ary.flatten: small_pairs_ary.flatten + small_pairs_ary.flatten!: small_pairs_ary.dup.flatten! + large_pairs_ary.flatten: large_pairs_ary.flatten + large_pairs_ary.flatten!: large_pairs_ary.dup.flatten! + mostly_flat_ary.flatten: mostly_flat_ary.flatten + mostly_flat_ary.flatten!: mostly_flat_ary.dup.flatten! +loop_count: 10000 diff --git a/benchmark/array_intersection.yml b/benchmark/array_intersection.yml new file mode 100644 index 0000000000..26705323fd --- /dev/null +++ b/benchmark/array_intersection.yml @@ -0,0 +1,14 @@ +prelude: | + small1 = [1, 2, 3] + small2 = [1, 2, 3, 4, 5] + small3 = [2, 3, 4, 5] + small4 = [2] + big1 = [1, 2, 3, 4] * 64 + big2 = [1, 2, 3] * 64 + big3 = [1, 2] * 64 + +benchmark: + small-&: small1 & small2 & small3 & small4 + small-intersection: small1.intersection(small2, small3, small4) + big-&: big1 & big2 & big3 + big-intersection: big1.intersection(big2, big3) diff --git a/benchmark/array_large_literal.yml b/benchmark/array_large_literal.yml new file mode 100644 index 0000000000..423d68391f --- /dev/null +++ b/benchmark/array_large_literal.yml @@ -0,0 +1,19 @@ +prelude: | + def def_array(size) + Object.class_eval(<<-END) + def array_#{size} + x = 1 + [#{(['x'] * size).join(',')}] + end + END + end + def_array(100) + def_array(1000) + def_array(10000) + def_array(100000) +benchmark: + array_100: array_100 + array_1000: array_1000 + array_10000: array_10000 + array_100000: array_100000 + diff --git a/benchmark/array_max_float.yml b/benchmark/array_max_float.yml new file mode 100644 index 0000000000..ace1ae2e14 --- /dev/null +++ b/benchmark/array_max_float.yml @@ -0,0 +1,30 @@ +prelude: | + ary2 = 2.times.map(&:to_f).shuffle + ary10 = 10.times.map(&:to_f).shuffle + ary100 = 100.times.map(&:to_f).shuffle + ary500 = 500.times.map(&:to_f).shuffle + ary1000 = 1000.times.map(&:to_f).shuffle + ary2000 = 2500.times.map(&:to_f).shuffle + ary3000 = 2500.times.map(&:to_f).shuffle + ary5000 = 5000.times.map(&:to_f).shuffle + ary10000 = 10000.times.map(&:to_f).shuffle + ary20000 = 20000.times.map(&:to_f).shuffle + ary50000 = 50000.times.map(&:to_f).shuffle + ary100000 = 100000.times.map(&:to_f).shuffle + +benchmark: + ary2.max: ary2.max + ary10.max: ary10.max + ary100.max: ary100.max + ary500.max: ary500.max + ary1000.max: ary1000.max + ary2000.max: ary2000.max + ary3000.max: ary3000.max + ary5000.max: ary5000.max + ary10000.max: ary10000.max + ary20000.max: ary20000.max + ary50000.max: ary50000.max + ary100000.max: ary100000.max + +loop_count: 10000 + diff --git a/benchmark/array_max_int.yml b/benchmark/array_max_int.yml new file mode 100644 index 0000000000..acd83684d0 --- /dev/null +++ b/benchmark/array_max_int.yml @@ -0,0 +1,31 @@ +prelude: | + ary2 = 2.times.to_a.shuffle + ary10 = 10.times.to_a.shuffle + ary100 = 100.times.to_a.shuffle + ary500 = 500.times.to_a.shuffle + ary1000 = 1000.times.to_a.shuffle + ary2000 = 2500.times.to_a.shuffle + ary3000 = 2500.times.to_a.shuffle + ary5000 = 5000.times.to_a.shuffle + ary10000 = 10000.times.to_a.shuffle + ary20000 = 20000.times.to_a.shuffle + ary50000 = 50000.times.to_a.shuffle + ary100000 = 100000.times.to_a.shuffle + ary1000000 = 1000000.times.to_a.shuffle + +benchmark: + ary2.max: ary2.max + ary10.max: ary10.max + ary100.max: ary100.max + ary500.max: ary500.max + ary1000.max: ary1000.max + ary2000.max: ary2000.max + ary3000.max: ary3000.max + ary5000.max: ary5000.max + ary10000.max: ary10000.max + ary20000.max: ary20000.max + ary50000.max: ary50000.max + ary100000.max: ary100000.max + ary1000000.max: ary1000000.max + +loop_count: 10000 diff --git a/benchmark/array_max_str.yml b/benchmark/array_max_str.yml new file mode 100644 index 0000000000..2aeed010f2 --- /dev/null +++ b/benchmark/array_max_str.yml @@ -0,0 +1,30 @@ +prelude: | + ary2 = 2.times.map(&:to_s).shuffle + ary10 = 10.times.map(&:to_s).shuffle + ary100 = 100.times.map(&:to_s).shuffle + ary500 = 500.times.map(&:to_s).shuffle + ary1000 = 1000.times.map(&:to_s).shuffle + ary2000 = 2500.times.map(&:to_s).shuffle + ary3000 = 2500.times.map(&:to_s).shuffle + ary5000 = 5000.times.map(&:to_s).shuffle + ary10000 = 10000.times.map(&:to_s).shuffle + ary20000 = 20000.times.map(&:to_s).shuffle + ary50000 = 50000.times.map(&:to_s).shuffle + ary100000 = 100000.times.map(&:to_s).shuffle + +benchmark: + ary2.max: ary2.max + ary10.max: ary10.max + ary100.max: ary100.max + ary500.max: ary500.max + ary1000.max: ary1000.max + ary2000.max: ary2000.max + ary3000.max: ary3000.max + ary5000.max: ary5000.max + ary10000.max: ary10000.max + ary20000.max: ary20000.max + ary50000.max: ary50000.max + ary100000.max: ary100000.max + +loop_count: 10000 + diff --git a/benchmark/array_min.yml b/benchmark/array_min.yml new file mode 100644 index 0000000000..53e5072b14 --- /dev/null +++ b/benchmark/array_min.yml @@ -0,0 +1,31 @@ +prelude: | + ary2 = 2.times.to_a.shuffle + ary10 = 10.times.to_a.shuffle + ary100 = 100.times.to_a.shuffle + ary500 = 500.times.to_a.shuffle + ary1000 = 1000.times.to_a.shuffle + ary2000 = 2500.times.to_a.shuffle + ary3000 = 2500.times.to_a.shuffle + ary5000 = 5000.times.to_a.shuffle + ary10000 = 10000.times.to_a.shuffle + ary20000 = 20000.times.to_a.shuffle + ary50000 = 50000.times.to_a.shuffle + ary100000 = 100000.times.to_a.shuffle + ary1000000 = 1000000.times.to_a.shuffle + +benchmark: + ary2.min: ary2.min + ary10.min: ary10.min + ary100.min: ary100.min + ary500.min: ary500.min + ary1000.min: ary1000.min + ary2000.min: ary2000.min + ary3000.min: ary3000.min + ary5000.min: ary5000.min + ary10000.min: ary10000.min + ary20000.min: ary20000.min + ary50000.min: ary50000.min + ary100000.min: ary100000.min + ary1000000.min: ary1000000.min + +loop_count: 10000 diff --git a/benchmark/array_sample.yml b/benchmark/array_sample.yml new file mode 100644 index 0000000000..1cd2b34794 --- /dev/null +++ b/benchmark/array_sample.yml @@ -0,0 +1,4 @@ +prelude: ary = (1..10_000).to_a +benchmark: + - ary.sample + - ary.sample(2) diff --git a/benchmark/array_sample_100k_10.rb b/benchmark/array_sample_100k_10.rb new file mode 100644 index 0000000000..5f41ecc32b --- /dev/null +++ b/benchmark/array_sample_100k_10.rb @@ -0,0 +1,2 @@ +arr = [*0...100000] +10_000.times {arr.sample 10} diff --git a/benchmark/array_sample_100k_11.rb b/benchmark/array_sample_100k_11.rb new file mode 100644 index 0000000000..18b1715319 --- /dev/null +++ b/benchmark/array_sample_100k_11.rb @@ -0,0 +1,2 @@ +arr = [*0...100000] +10_000.times {arr.sample 11} diff --git a/benchmark/array_sample_100k__100.rb b/benchmark/array_sample_100k__100.rb new file mode 100644 index 0000000000..22863afe89 --- /dev/null +++ b/benchmark/array_sample_100k__100.rb @@ -0,0 +1,2 @@ +arr = [*0...100000] +10_000.times {arr.sample 100} diff --git a/benchmark/array_sample_100k__1k.rb b/benchmark/array_sample_100k__1k.rb new file mode 100644 index 0000000000..4cd79e6c67 --- /dev/null +++ b/benchmark/array_sample_100k__1k.rb @@ -0,0 +1,2 @@ +arr = [*0...100000] +10_000.times {arr.sample 1000} diff --git a/benchmark/array_sample_100k__6k.rb b/benchmark/array_sample_100k__6k.rb new file mode 100644 index 0000000000..b3d264249e --- /dev/null +++ b/benchmark/array_sample_100k__6k.rb @@ -0,0 +1,2 @@ +arr = [*0...100000] +10_000.times {arr.sample 6000} diff --git a/benchmark/array_sample_100k___10k.rb b/benchmark/array_sample_100k___10k.rb new file mode 100644 index 0000000000..5dd55ec058 --- /dev/null +++ b/benchmark/array_sample_100k___10k.rb @@ -0,0 +1,2 @@ +arr = [*0...100000] +10_000.times {arr.sample 10_000} diff --git a/benchmark/array_sample_100k___50k.rb b/benchmark/array_sample_100k___50k.rb new file mode 100644 index 0000000000..1506732c3c --- /dev/null +++ b/benchmark/array_sample_100k___50k.rb @@ -0,0 +1,2 @@ +arr = [*0...100000] +10_000.times {arr.sample 50_000} diff --git a/benchmark/array_shift.rb b/benchmark/array_shift.rb new file mode 100644 index 0000000000..798bb9e3f4 --- /dev/null +++ b/benchmark/array_shift.rb @@ -0,0 +1,14 @@ +require 'benchmark' + +Benchmark.bm do |x| + [10_000,1_000_000,100_000_000].each do |n| + ary = Array.new(n,0) + GC.start + x.report("#{n}:shift"){ ary.shift } + (0..4).each do |i| + ary = Array.new(n,0) + GC.start + x.report("#{n}:shift(#{i})"){ ary.shift(i) } + end + end +end diff --git a/benchmark/array_small_and.rb b/benchmark/array_small_and.rb new file mode 100644 index 0000000000..e53a6edae6 --- /dev/null +++ b/benchmark/array_small_and.rb @@ -0,0 +1,17 @@ +MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i +MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i +ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i + +ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1| + (MIN_SIZE..MAX_SIZE).map do |size2| + [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }] + end +end + +ITERATIONS.times do + ARRAYS.each do |group| + group.each do |arr1, arr2| + arr1 & arr2 + end + end +end diff --git a/benchmark/array_small_diff.rb b/benchmark/array_small_diff.rb new file mode 100644 index 0000000000..9661ee48db --- /dev/null +++ b/benchmark/array_small_diff.rb @@ -0,0 +1,17 @@ +MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i +MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i +ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i + +ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1| + (MIN_SIZE..MAX_SIZE).map do |size2| + [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }] + end +end + +ITERATIONS.times do + ARRAYS.each do |group| + group.each do |arr1, arr2| + arr1 - arr2 + end + end +end diff --git a/benchmark/array_small_or.rb b/benchmark/array_small_or.rb new file mode 100644 index 0000000000..c58b5fd1ff --- /dev/null +++ b/benchmark/array_small_or.rb @@ -0,0 +1,17 @@ +MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i +MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i +ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i + +ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1| + (MIN_SIZE..MAX_SIZE).map do |size2| + [Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }] + end +end + +ITERATIONS.times do + ARRAYS.each do |group| + group.each do |arr1, arr2| + arr1 | arr2 + end + end +end diff --git a/benchmark/array_sort_block.rb b/benchmark/array_sort_block.rb new file mode 100644 index 0000000000..3579786056 --- /dev/null +++ b/benchmark/array_sort_block.rb @@ -0,0 +1,2 @@ +ary = Array.new(1000) { rand(1000) } +10000.times { ary.sort { |a, b| a <=> b } } diff --git a/benchmark/array_sort_float.rb b/benchmark/array_sort_float.rb new file mode 100644 index 0000000000..9a6e2f8bd2 --- /dev/null +++ b/benchmark/array_sort_float.rb @@ -0,0 +1,2 @@ +arr = Array.new(1000) { rand } +10000.times { arr.sort } diff --git a/benchmark/array_sort_int.yml b/benchmark/array_sort_int.yml new file mode 100644 index 0000000000..7b9027ebf7 --- /dev/null +++ b/benchmark/array_sort_int.yml @@ -0,0 +1,15 @@ +prelude: | + ary2 = 2.times.to_a.shuffle + ary10 = 10.times.to_a.shuffle + ary100 = 100.times.to_a.shuffle + ary1000 = 1000.times.to_a.shuffle + ary10000 = 10000.times.to_a.shuffle + +benchmark: + ary2.sort: ary2.sort + ary10.sort: ary10.sort + ary100.sort: ary100.sort + ary1000.sort: ary1000.sort + ary10000.sort: ary10000.sort + +loop_count: 10000 diff --git a/benchmark/array_values_at_int.rb b/benchmark/array_values_at_int.rb new file mode 100644 index 0000000000..6cb394cb9f --- /dev/null +++ b/benchmark/array_values_at_int.rb @@ -0,0 +1,2 @@ +ary = Array.new(10000) {|i| i} +100000.times { ary.values_at(500) } diff --git a/benchmark/array_values_at_range.rb b/benchmark/array_values_at_range.rb new file mode 100644 index 0000000000..5b53806d1c --- /dev/null +++ b/benchmark/array_values_at_range.rb @@ -0,0 +1,2 @@ +ary = Array.new(10000) {|i| i} +100000.times { ary.values_at(1..2000) } diff --git a/benchmark/attr_accessor.yml b/benchmark/attr_accessor.yml new file mode 100644 index 0000000000..82134cdf9b --- /dev/null +++ b/benchmark/attr_accessor.yml @@ -0,0 +1,29 @@ +prelude: | + class C + attr_accessor :x + def initialize + @x = nil + end + class_eval <<-END + def ar + #{'x;'*256} + end + def aw + #{'self.x = nil;'*256} + end + def arm + m = method(:x) + #{'m.call;'*256} + end + def awm + m = method(:x=) + #{'m.call(nil);'*256} + end + END + end + obj = C.new +benchmark: + attr_reader: "obj.ar" + attr_writer: "obj.aw" + attr_reader_method: "obj.arm" + attr_writer_method: "obj.awm" diff --git a/benchmark/bighash.rb b/benchmark/bighash.rb new file mode 100644 index 0000000000..e2ad5a5c94 --- /dev/null +++ b/benchmark/bighash.rb @@ -0,0 +1 @@ +h = {}; 5000000.times {|n| h[n] = n } diff --git a/benchmark/bm_app_erb.rb b/benchmark/bm_app_erb.rb deleted file mode 100644 index 77c66a7949..0000000000 --- a/benchmark/bm_app_erb.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# Create many HTML strings with ERB. -# - -require 'erb' - -data = DATA.read -max = 15_000 -title = "hello world!" -content = "hello world!\n" * 10 - -max.times{ - ERB.new(data).result(binding) -} - -__END__ - -<html> - <head> <%= title %> </head> - <body> - <h1> <%= title %> </h1> - <p> - <%= content %> - </p> - </body> -</html> diff --git a/benchmark/bm_hash_aref_sym.rb b/benchmark/bm_hash_aref_sym.rb deleted file mode 100644 index 54298ffc9e..0000000000 --- a/benchmark/bm_hash_aref_sym.rb +++ /dev/null @@ -1,4 +0,0 @@ -h = {} -syms = ('a'..'z').to_a.map(&:to_sym) -syms.each { |s| h[s] = s } -200_000.times { syms.each { |s| h[s] } } diff --git a/benchmark/bm_so_count_words.rb b/benchmark/bm_so_count_words.rb deleted file mode 100644 index 65f6337a4a..0000000000 --- a/benchmark/bm_so_count_words.rb +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/ruby -# -*- mode: ruby -*- -# $Id: wc-ruby.code,v 1.4 2004/11/13 07:43:32 bfulgham Exp $ -# http://www.bagley.org/~doug/shootout/ -# with help from Paul Brannan - -input = open(File.join(File.dirname($0), 'wc.input'), 'rb') - -nl = nw = nc = 0 -while true - tmp = input.read(4096) or break - data = tmp << (input.gets || "") - nc += data.length - nl += data.count("\n") - ((data.strip! || data).tr!("\n", " ") || data).squeeze! - nw += data.count(" ") + 1 -end -# STDERR.puts "#{nl} #{nw} #{nc}" - diff --git a/benchmark/bm_so_k_nucleotide.rb b/benchmark/bm_so_k_nucleotide.rb deleted file mode 100644 index dadab3e79c..0000000000 --- a/benchmark/bm_so_k_nucleotide.rb +++ /dev/null @@ -1,48 +0,0 @@ -# The Computer Language Shootout -# http://shootout.alioth.debian.org -# -# contributed by jose fco. gonzalez -# modified by Sokolov Yura - -seq = String.new - -def frecuency( seq,length ) - n, table = seq.length - length + 1, Hash.new(0) - f, i = nil, nil - (0 ... length).each do |f| - (f ... n).step(length) do |i| - table[seq[i,length]] += 1 - end - end - [n,table] - -end - -def sort_by_freq( seq,length ) - n,table = frecuency( seq,length ) - a, b, v = nil, nil, nil - table.sort{|a,b| b[1] <=> a[1]}.each do |v| - puts "%s %.3f" % [v[0].upcase,((v[1]*100).to_f/n)] - end - puts -end - -def find_seq( seq,s ) - n,table = frecuency( seq,s.length ) - puts "#{table[s].to_s}\t#{s.upcase}" -end - -input = open(File.join(File.dirname($0), 'fasta.output.100000'), 'rb') - -line = input.gets while line !~ /^>THREE/ -line = input.gets - -while (line !~ /^>/) & line do - seq << line.chomp - line = input.gets -end - -[1,2].each {|i| sort_by_freq( seq,i ) } - -%w(ggt ggta ggtatt ggtattttaatt ggtattttaatttatagt).each{|s| find_seq( seq,s) } - diff --git a/benchmark/bm_so_reverse_complement.rb b/benchmark/bm_so_reverse_complement.rb deleted file mode 100644 index 82ea666994..0000000000 --- a/benchmark/bm_so_reverse_complement.rb +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/ruby -# The Great Computer Language Shootout -# http://shootout.alioth.debian.org/ -# -# Contributed by Peter Bjarke Olsen -# Modified by Doug King - -seq=Array.new - -def revcomp(seq) - seq.reverse!.tr!('wsatugcyrkmbdhvnATUGCYRKMBDHVN','WSTAACGRYMKVHDBNTAACGRYMKVHDBN') - stringlen=seq.length - 0.step(stringlen-1,60) {|x| print seq.slice(x,60) , "\n"} -end - -input = open(File.join(File.dirname($0), 'fasta.output.2500000'), 'rb') - -while input.gets - if $_ =~ />/ - if seq.length != 0 - revcomp(seq.join) - seq=Array.new - end - puts $_ - else - $_.sub(/\n/,'') - seq.push $_ - end -end -revcomp(seq.join) diff --git a/benchmark/bm_vm1_attr_ivar.rb b/benchmark/bm_vm1_attr_ivar.rb deleted file mode 100644 index 16906f3605..0000000000 --- a/benchmark/bm_vm1_attr_ivar.rb +++ /dev/null @@ -1,14 +0,0 @@ -class C - attr_reader :a, :b - def initialize - @a = nil - @b = nil - end -end -obj = C.new -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - j = obj.a - k = obj.b -end diff --git a/benchmark/bm_vm1_attr_ivar_set.rb b/benchmark/bm_vm1_attr_ivar_set.rb deleted file mode 100644 index 7e7a6b48c0..0000000000 --- a/benchmark/bm_vm1_attr_ivar_set.rb +++ /dev/null @@ -1,14 +0,0 @@ -class C - attr_accessor :a, :b - def initialize - @a = nil - @b = nil - end -end -obj = C.new -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - obj.a = 1 - obj.b = 2 -end diff --git a/benchmark/bm_vm1_block.rb b/benchmark/bm_vm1_block.rb deleted file mode 100644 index a9f56b15ea..0000000000 --- a/benchmark/bm_vm1_block.rb +++ /dev/null @@ -1,10 +0,0 @@ -def m - yield -end - -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - m{ - } -end diff --git a/benchmark/bm_vm1_const.rb b/benchmark/bm_vm1_const.rb deleted file mode 100644 index ac59ebccf1..0000000000 --- a/benchmark/bm_vm1_const.rb +++ /dev/null @@ -1,8 +0,0 @@ -Const = 1 - -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - j = Const - k = Const -end diff --git a/benchmark/bm_vm1_ensure.rb b/benchmark/bm_vm1_ensure.rb deleted file mode 100644 index a1596145f2..0000000000 --- a/benchmark/bm_vm1_ensure.rb +++ /dev/null @@ -1,11 +0,0 @@ -i = 0 -while i<30_000_000 # benchmark loop 1 - i += 1 - begin - begin - ensure - end - ensure - end -end - diff --git a/benchmark/bm_vm1_float_simple.rb b/benchmark/bm_vm1_float_simple.rb deleted file mode 100644 index d4581439ff..0000000000 --- a/benchmark/bm_vm1_float_simple.rb +++ /dev/null @@ -1,7 +0,0 @@ -i = 0.0; f = 0.0 -while i<30_000_000 - i += 1 - f += 0.1; f -= 0.1 - f += 0.1; f -= 0.1 - f += 0.1; f -= 0.1 -end diff --git a/benchmark/bm_vm1_gc_short_lived.rb b/benchmark/bm_vm1_gc_short_lived.rb deleted file mode 100644 index e78bca5668..0000000000 --- a/benchmark/bm_vm1_gc_short_lived.rb +++ /dev/null @@ -1,10 +0,0 @@ -i = 0 -while i<30_000_000 # while loop 1 - a = '' # short-lived String - b = '' - c = '' - d = '' - e = '' - f = '' - i+=1 -end diff --git a/benchmark/bm_vm1_gc_short_with_complex_long.rb b/benchmark/bm_vm1_gc_short_with_complex_long.rb deleted file mode 100644 index b66052dee0..0000000000 --- a/benchmark/bm_vm1_gc_short_with_complex_long.rb +++ /dev/null @@ -1,27 +0,0 @@ -def nested_hash h, n - if n == 0 - '' - else - 10.times{ - h[Object.new] = nested_hash(h, n-1) - } - end -end - -long_lived = Hash.new -nested_hash long_lived, 6 - -GC.start -GC.start - -i = 0 -while i<30_000_000 # while loop 1 - a = '' # short-lived String - b = '' - c = '' - d = '' - e = '' - f = '' - i+=1 -end - diff --git a/benchmark/bm_vm1_gc_short_with_long.rb b/benchmark/bm_vm1_gc_short_with_long.rb deleted file mode 100644 index 298dbc845b..0000000000 --- a/benchmark/bm_vm1_gc_short_with_long.rb +++ /dev/null @@ -1,13 +0,0 @@ -long_lived = Array.new(1_000_000){|i| "#{i}"} -GC.start -GC.start -i = 0 -while i<30_000_000 # while loop 1 - a = '' # short-lived String - b = '' - c = '' - d = '' - e = '' - f = '' - i+=1 -end diff --git a/benchmark/bm_vm1_gc_short_with_symbol.rb b/benchmark/bm_vm1_gc_short_with_symbol.rb deleted file mode 100644 index 6b15c1b7bf..0000000000 --- a/benchmark/bm_vm1_gc_short_with_symbol.rb +++ /dev/null @@ -1,15 +0,0 @@ -# make many symbols -50_000.times{|i| sym = "sym#{i}".to_sym} -GC.start -GC.start - -i = 0 -while i<30_000_000 # while loop 1 - a = '' # short-lived String - b = '' - c = '' - d = '' - e = '' - f = '' - i+=1 -end diff --git a/benchmark/bm_vm1_gc_wb_ary.rb b/benchmark/bm_vm1_gc_wb_ary.rb deleted file mode 100644 index ecfab51dbf..0000000000 --- a/benchmark/bm_vm1_gc_wb_ary.rb +++ /dev/null @@ -1,10 +0,0 @@ -long_lived = [] -GC.start -GC.start - -i = 0 -short_lived = '' -while i<30_000_000 # while loop 1 - long_lived[0] = short_lived # write barrier - i+=1 -end diff --git a/benchmark/bm_vm1_gc_wb_obj.rb b/benchmark/bm_vm1_gc_wb_obj.rb deleted file mode 100644 index 017eff4f94..0000000000 --- a/benchmark/bm_vm1_gc_wb_obj.rb +++ /dev/null @@ -1,13 +0,0 @@ -class C - attr_accessor :foo -end -long_lived = C.new -GC.start -GC.start - -i = 0 -short_lived = '' -while i<30_000_000 # while loop 1 - long_lived.foo = short_lived # write barrier - i+=1 -end diff --git a/benchmark/bm_vm1_ivar.rb b/benchmark/bm_vm1_ivar.rb deleted file mode 100644 index 68a73cf92f..0000000000 --- a/benchmark/bm_vm1_ivar.rb +++ /dev/null @@ -1,8 +0,0 @@ -@a = 1 - -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - j = @a - k = @a -end diff --git a/benchmark/bm_vm1_ivar_set.rb b/benchmark/bm_vm1_ivar_set.rb deleted file mode 100644 index bd81b06c34..0000000000 --- a/benchmark/bm_vm1_ivar_set.rb +++ /dev/null @@ -1,6 +0,0 @@ -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - @a = 1 - @b = 2 -end diff --git a/benchmark/bm_vm1_length.rb b/benchmark/bm_vm1_length.rb deleted file mode 100644 index 353de3ab0e..0000000000 --- a/benchmark/bm_vm1_length.rb +++ /dev/null @@ -1,9 +0,0 @@ -a = 'abc' -b = [1, 2, 3] -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - a.length - b.length -end - diff --git a/benchmark/bm_vm1_lvar_init.rb b/benchmark/bm_vm1_lvar_init.rb deleted file mode 100644 index 36f2068811..0000000000 --- a/benchmark/bm_vm1_lvar_init.rb +++ /dev/null @@ -1,18 +0,0 @@ -def m v - unless v - # unreachable code - v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = v10 = - v11 = v12 = v13 = v14 = v15 = v16 = v17 = v18 = v19 = v20 = - v21 = v22 = v23 = v24 = v25 = v26 = v27 = v28 = v29 = v30 = - v31 = v32 = v33 = v34 = v35 = v36 = v37 = v38 = v39 = v40 = - v41 = v42 = v43 = v44 = v45 = v46 = v47 = v48 = v49 = v50 = 1 - end -end - -i = 0 - -while i<30_000_000 # while loop 1 - i += 1 - m i -end - diff --git a/benchmark/bm_vm1_lvar_set.rb b/benchmark/bm_vm1_lvar_set.rb deleted file mode 100644 index 222e864134..0000000000 --- a/benchmark/bm_vm1_lvar_set.rb +++ /dev/null @@ -1,5 +0,0 @@ -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - a = b = c = d = e = f = g = h = j = k = l = m = n = o = p = q = r = 1 -end diff --git a/benchmark/bm_vm1_neq.rb b/benchmark/bm_vm1_neq.rb deleted file mode 100644 index bbb4ae07a4..0000000000 --- a/benchmark/bm_vm1_neq.rb +++ /dev/null @@ -1,8 +0,0 @@ -i = 0 -obj1 = Object.new -obj2 = Object.new - -while i<30_000_000 # while loop 1 - i += 1 - obj1 != obj2 -end diff --git a/benchmark/bm_vm1_not.rb b/benchmark/bm_vm1_not.rb deleted file mode 100644 index b09ecdcc21..0000000000 --- a/benchmark/bm_vm1_not.rb +++ /dev/null @@ -1,7 +0,0 @@ -i = 0 -obj = Object.new - -while i<30_000_000 # while loop 1 - i += 1 - !obj -end diff --git a/benchmark/bm_vm1_rescue.rb b/benchmark/bm_vm1_rescue.rb deleted file mode 100644 index b0d3e2bdfa..0000000000 --- a/benchmark/bm_vm1_rescue.rb +++ /dev/null @@ -1,7 +0,0 @@ -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - begin - rescue - end -end diff --git a/benchmark/bm_vm1_simplereturn.rb b/benchmark/bm_vm1_simplereturn.rb deleted file mode 100644 index 63f9f21675..0000000000 --- a/benchmark/bm_vm1_simplereturn.rb +++ /dev/null @@ -1,9 +0,0 @@ -def m - return 1 -end -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - m -end - diff --git a/benchmark/bm_vm1_swap.rb b/benchmark/bm_vm1_swap.rb deleted file mode 100644 index 918f8b2112..0000000000 --- a/benchmark/bm_vm1_swap.rb +++ /dev/null @@ -1,8 +0,0 @@ -a = 1 -b = 2 -i = 0 -while i<30_000_000 # while loop 1 - i += 1 - a, b = b, a -end - diff --git a/benchmark/bm_vm1_yield.rb b/benchmark/bm_vm1_yield.rb deleted file mode 100644 index 775597cea6..0000000000 --- a/benchmark/bm_vm1_yield.rb +++ /dev/null @@ -1,10 +0,0 @@ -def m - i = 0 - while i<30_000_000 # while loop 1 - i += 1 - yield - end -end - -m{} - diff --git a/benchmark/bm_vm2_bigarray.rb b/benchmark/bm_vm2_bigarray.rb deleted file mode 100644 index b02509d6a2..0000000000 --- a/benchmark/bm_vm2_bigarray.rb +++ /dev/null @@ -1,106 +0,0 @@ -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - a = [ - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - 1,2,3,4,5,6,7,8,9,10, - ] -end diff --git a/benchmark/bm_vm2_bighash.rb b/benchmark/bm_vm2_bighash.rb deleted file mode 100644 index 5e3f437bb8..0000000000 --- a/benchmark/bm_vm2_bighash.rb +++ /dev/null @@ -1,5 +0,0 @@ -i = 0 -while i<60_000 # benchmark loop 2 - i += 1 - a = {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, 10=>10, 11=>11, 12=>12, 13=>13, 14=>14, 15=>15, 16=>16, 17=>17, 18=>18, 19=>19, 20=>20, 21=>21, 22=>22, 23=>23, 24=>24, 25=>25, 26=>26, 27=>27, 28=>28, 29=>29, 30=>30, 31=>31, 32=>32, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 38=>38, 39=>39, 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, 60=>60, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67, 68=>68, 69=>69, 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79, 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, 90=>90, 91=>91, 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, 100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, 110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, 120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126, 127=>127, 128=>128, 129=>129, 130=>130, 131=>131, 132=>132, 133=>133, 134=>134, 135=>135, 136=>136, 137=>137, 138=>138, 139=>139, 140=>140, 141=>141, 142=>142, 143=>143, 144=>144, 145=>145, 146=>146, 147=>147, 148=>148, 149=>149, 150=>150, 151=>151, 152=>152, 153=>153, 154=>154, 155=>155, 156=>156, 157=>157, 158=>158, 159=>159, 160=>160, 161=>161, 162=>162, 163=>163, 164=>164, 165=>165, 166=>166, 167=>167, 168=>168, 169=>169, 170=>170, 171=>171, 172=>172, 173=>173, 174=>174, 175=>175, 176=>176, 177=>177, 178=>178, 179=>179, 180=>180, 181=>181, 182=>182, 183=>183, 184=>184, 185=>185, 186=>186, 187=>187, 188=>188, 189=>189, 190=>190, 191=>191, 192=>192, 193=>193, 194=>194, 195=>195, 196=>196, 197=>197, 198=>198, 199=>199, 200=>200, 201=>201, 202=>202, 203=>203, 204=>204, 205=>205, 206=>206, 207=>207, 208=>208, 209=>209, 210=>210, 211=>211, 212=>212, 213=>213, 214=>214, 215=>215, 216=>216, 217=>217, 218=>218, 219=>219, 220=>220, 221=>221, 222=>222, 223=>223, 224=>224, 225=>225, 226=>226, 227=>227, 228=>228, 229=>229, 230=>230, 231=>231, 232=>232, 233=>233, 234=>234, 235=>235, 236=>236, 237=>237, 238=>238, 239=>239, 240=>240, 241=>241, 242=>242, 243=>243, 244=>244, 245=>245, 246=>246, 247=>247, 248=>248, 249=>249, 250=>250, 251=>251, 252=>252, 253=>253, 254=>254, 255=>255, 256=>256, 257=>257, 258=>258, 259=>259, 260=>260, 261=>261, 262=>262, 263=>263, 264=>264, 265=>265, 266=>266, 267=>267, 268=>268, 269=>269, 270=>270, 271=>271, 272=>272, 273=>273, 274=>274, 275=>275, 276=>276, 277=>277, 278=>278, 279=>279, 280=>280, 281=>281, 282=>282, 283=>283, 284=>284, 285=>285, 286=>286, 287=>287, 288=>288, 289=>289, 290=>290, 291=>291, 292=>292, 293=>293, 294=>294, 295=>295, 296=>296, 297=>297, 298=>298, 299=>299, 300=>300, 301=>301, 302=>302, 303=>303, 304=>304, 305=>305, 306=>306, 307=>307, 308=>308, 309=>309, 310=>310, 311=>311, 312=>312, 313=>313, 314=>314, 315=>315, 316=>316, 317=>317, 318=>318, 319=>319, 320=>320, 321=>321, 322=>322, 323=>323, 324=>324, 325=>325, 326=>326, 327=>327, 328=>328, 329=>329, 330=>330, 331=>331, 332=>332, 333=>333, 334=>334, 335=>335, 336=>336, 337=>337, 338=>338, 339=>339, 340=>340, 341=>341, 342=>342, 343=>343, 344=>344, 345=>345, 346=>346, 347=>347, 348=>348, 349=>349, 350=>350, 351=>351, 352=>352, 353=>353, 354=>354, 355=>355, 356=>356, 357=>357, 358=>358, 359=>359, 360=>360, 361=>361, 362=>362, 363=>363, 364=>364, 365=>365, 366=>366, 367=>367, 368=>368, 369=>369, 370=>370, 371=>371, 372=>372, 373=>373, 374=>374, 375=>375, 376=>376, 377=>377, 378=>378, 379=>379, 380=>380, 381=>381, 382=>382, 383=>383, 384=>384, 385=>385, 386=>386, 387=>387, 388=>388, 389=>389, 390=>390, 391=>391, 392=>392, 393=>393, 394=>394, 395=>395, 396=>396, 397=>397, 398=>398, 399=>399, 400=>400, 401=>401, 402=>402, 403=>403, 404=>404, 405=>405, 406=>406, 407=>407, 408=>408, 409=>409, 410=>410, 411=>411, 412=>412, 413=>413, 414=>414, 415=>415, 416=>416, 417=>417, 418=>418, 419=>419, 420=>420, 421=>421, 422=>422, 423=>423, 424=>424, 425=>425, 426=>426, 427=>427, 428=>428, 429=>429, 430=>430, 431=>431, 432=>432, 433=>433, 434=>434, 435=>435, 436=>436, 437=>437, 438=>438, 439=>439, 440=>440, 441=>441, 442=>442, 443=>443, 444=>444, 445=>445, 446=>446, 447=>447, 448=>448, 449=>449, 450=>450, 451=>451, 452=>452, 453=>453, 454=>454, 455=>455, 456=>456, 457=>457, 458=>458, 459=>459, 460=>460, 461=>461, 462=>462, 463=>463, 464=>464, 465=>465, 466=>466, 467=>467, 468=>468, 469=>469, 470=>470, 471=>471, 472=>472, 473=>473, 474=>474, 475=>475, 476=>476, 477=>477, 478=>478, 479=>479, 480=>480, 481=>481, 482=>482, 483=>483, 484=>484, 485=>485, 486=>486, 487=>487, 488=>488, 489=>489, 490=>490, 491=>491, 492=>492, 493=>493, 494=>494, 495=>495, 496=>496, 497=>497, 498=>498, 499=>499, 500=>500,} -end diff --git a/benchmark/bm_vm2_case.rb b/benchmark/bm_vm2_case.rb deleted file mode 100644 index adc6e4df0a..0000000000 --- a/benchmark/bm_vm2_case.rb +++ /dev/null @@ -1,14 +0,0 @@ -i = 0 -while i<6_000_000 # while loop 2 - case :foo - when :bar - raise - when :baz - raise - when :boo - raise - when :foo - i += 1 - end -end - diff --git a/benchmark/bm_vm2_defined_method.rb b/benchmark/bm_vm2_defined_method.rb deleted file mode 100644 index 053ed6c912..0000000000 --- a/benchmark/bm_vm2_defined_method.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Object - define_method(:m){} -end - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - m; m; m; m; m; m; m; m; -end diff --git a/benchmark/bm_vm2_method_missing.rb b/benchmark/bm_vm2_method_missing.rb deleted file mode 100644 index 2badc73101..0000000000 --- a/benchmark/bm_vm2_method_missing.rb +++ /dev/null @@ -1,12 +0,0 @@ -class C - def method_missing mid - end -end - -obj = C.new - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; -end diff --git a/benchmark/bm_vm2_method_with_block.rb b/benchmark/bm_vm2_method_with_block.rb deleted file mode 100644 index b4efb4f520..0000000000 --- a/benchmark/bm_vm2_method_with_block.rb +++ /dev/null @@ -1,9 +0,0 @@ -def m - nil -end - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - m{}; m{}; m{}; m{}; m{}; m{}; m{}; m{}; -end diff --git a/benchmark/bm_vm2_mutex.rb b/benchmark/bm_vm2_mutex.rb deleted file mode 100644 index 7362f738c5..0000000000 --- a/benchmark/bm_vm2_mutex.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'thread' - -m = Mutex.new - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - m.synchronize{} -end diff --git a/benchmark/bm_vm2_poly_method.rb b/benchmark/bm_vm2_poly_method.rb deleted file mode 100644 index c82c0e4bce..0000000000 --- a/benchmark/bm_vm2_poly_method.rb +++ /dev/null @@ -1,20 +0,0 @@ -class C1 - def m - 1 - end -end -class C2 - def m - 2 - end -end - -o1 = C1.new -o2 = C2.new - -i = 0 -while i<6_000_000 # benchmark loop 2 - o = (i % 2 == 0) ? o1 : o2 - o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m - i += 1 -end diff --git a/benchmark/bm_vm2_poly_method_ov.rb b/benchmark/bm_vm2_poly_method_ov.rb deleted file mode 100644 index aa5fd1dd38..0000000000 --- a/benchmark/bm_vm2_poly_method_ov.rb +++ /dev/null @@ -1,20 +0,0 @@ -class C1 - def m - 1 - end -end -class C2 - def m - 2 - end -end - -o1 = C1.new -o2 = C2.new - -i = 0 -while i<6_000_000 # benchmark loop 2 - o = (i % 2 == 0) ? o1 : o2 -# o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m - i += 1 -end diff --git a/benchmark/bm_vm2_proc.rb b/benchmark/bm_vm2_proc.rb deleted file mode 100644 index 65e5217371..0000000000 --- a/benchmark/bm_vm2_proc.rb +++ /dev/null @@ -1,14 +0,0 @@ -def m &b - b -end - -pr = m{ - a = 1 -} - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - pr.call -end - diff --git a/benchmark/bm_vm2_raise1.rb b/benchmark/bm_vm2_raise1.rb deleted file mode 100644 index aa5387987f..0000000000 --- a/benchmark/bm_vm2_raise1.rb +++ /dev/null @@ -1,18 +0,0 @@ -def rec n - if n > 0 - rec n-1 - else - raise - end -end - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - - begin - rec 1 - rescue - # ignore - end -end diff --git a/benchmark/bm_vm2_raise2.rb b/benchmark/bm_vm2_raise2.rb deleted file mode 100644 index 1f61c63157..0000000000 --- a/benchmark/bm_vm2_raise2.rb +++ /dev/null @@ -1,18 +0,0 @@ -def rec n - if n > 0 - rec n-1 - else - raise - end -end - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - - begin - rec 10 - rescue - # ignore - end -end diff --git a/benchmark/bm_vm2_send.rb b/benchmark/bm_vm2_send.rb deleted file mode 100644 index 6a3ab6fdab..0000000000 --- a/benchmark/bm_vm2_send.rb +++ /dev/null @@ -1,12 +0,0 @@ -class C - def m - end -end - -o = C.new - -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - o.__send__ :m -end diff --git a/benchmark/bm_vm2_super.rb b/benchmark/bm_vm2_super.rb deleted file mode 100644 index afd8579e7b..0000000000 --- a/benchmark/bm_vm2_super.rb +++ /dev/null @@ -1,20 +0,0 @@ - -class C - def m - 1 - end -end - -class CC < C - def m - super() - end -end - -obj = CC.new - -i = 0 -while i<6_000_000 # benchmark loop 2 - obj.m - i += 1 -end diff --git a/benchmark/bm_vm2_unif1.rb b/benchmark/bm_vm2_unif1.rb deleted file mode 100644 index 1774625942..0000000000 --- a/benchmark/bm_vm2_unif1.rb +++ /dev/null @@ -1,8 +0,0 @@ -i = 0 -def m a, b -end - -while i<6_000_000 # benchmark loop 2 - i += 1 - m 100, 200 -end diff --git a/benchmark/bm_vm2_zsuper.rb b/benchmark/bm_vm2_zsuper.rb deleted file mode 100644 index 2a43e62217..0000000000 --- a/benchmark/bm_vm2_zsuper.rb +++ /dev/null @@ -1,20 +0,0 @@ -i = 0 - -class C - def m a - 1 - end -end - -class CC < C - def m a - super - end -end - -obj = CC.new - -while i<6_000_000 # benchmark loop 2 - obj.m 10 - i += 1 -end diff --git a/benchmark/bm_vm_thread_alive_check1.rb b/benchmark/bm_vm_thread_alive_check1.rb deleted file mode 100644 index c993accdda..0000000000 --- a/benchmark/bm_vm_thread_alive_check1.rb +++ /dev/null @@ -1,6 +0,0 @@ -5_000.times{ - t = Thread.new{} - while t.alive? - Thread.pass - end -} diff --git a/benchmark/bm_vm_thread_pass_flood.rb b/benchmark/bm_vm_thread_pass_flood.rb deleted file mode 100644 index 27157d1a6f..0000000000 --- a/benchmark/bm_vm_thread_pass_flood.rb +++ /dev/null @@ -1,8 +0,0 @@ -1000.times{ - Thread.new{loop{Thread.pass}} -} - -i = 0 -while i<10000 - i += 1 -end diff --git a/benchmark/buffer_each.yml b/benchmark/buffer_each.yml new file mode 100644 index 0000000000..417941104e --- /dev/null +++ b/benchmark/buffer_each.yml @@ -0,0 +1,27 @@ +prelude: | + # frozen_string_literal: true + Warning[:experimental] = false + string = "The quick brown fox jumped over the lazy dog." + array = string.bytes + buffer = IO::Buffer.for(string) +benchmark: + string.each_byte: | + upcased = String.new + string.each_byte do |byte| + upcased << (byte ^ 32) + end + array.each: | + upcased = String.new + array.each do |byte| + upcased << (byte ^ 32) + end + buffer.each: | + upcased = String.new + buffer.each(:U8) do |offset, byte| + upcased << (byte ^ 32) + end + buffer.each_byte: | + upcased = String.new + buffer.each_byte do |byte| + upcased << (byte ^ 32) + end diff --git a/benchmark/buffer_get.yml b/benchmark/buffer_get.yml new file mode 100644 index 0000000000..9e1f99d64e --- /dev/null +++ b/benchmark/buffer_get.yml @@ -0,0 +1,25 @@ +prelude: | + # frozen_string_literal: true + Warning[:experimental] = false + string = "The quick brown fox jumped over the lazy dog." + buffer = IO::Buffer.for(string) + format = [:U32, :U32, :U32, :U32] +benchmark: + string.unpack1: | + [ + string.unpack1("N"), + string.unpack1("N", offset: 4), + string.unpack1("N", offset: 8), + string.unpack1("N", offset: 12), + ] + buffer.get_value: | + [ + buffer.get_value(:U32, 0), + buffer.get_value(:U32, 4), + buffer.get_value(:U32, 8), + buffer.get_value(:U32, 12), + ] + buffer.get_values: | + buffer.get_values(format, 0) + string.unpack: | + string.unpack("NNNN") diff --git a/benchmark/cgi_escape_html.yml b/benchmark/cgi_escape_html.yml new file mode 100644 index 0000000000..655be9d7d8 --- /dev/null +++ b/benchmark/cgi_escape_html.yml @@ -0,0 +1,31 @@ +prelude: | + # frozen_string_literal: true + require 'cgi/escape' +benchmark: + - script: CGI.escapeHTML("") + loop_count: 20000000 + - script: CGI.escapeHTML("abcde") + loop_count: 20000000 + - script: CGI.escapeHTML("abcd<") + loop_count: 20000000 + - script: CGI.escapeHTML("'&\"<>") + loop_count: 5000000 + - prelude: long_no_escape = "abcde" * 300 + script: CGI.escapeHTML(long_no_escape) + loop_count: 1000000 + - prelude: long_all_escape = "'&\"<>" * 10 + script: CGI.escapeHTML(long_all_escape) + loop_count: 1000000 + - prelude: | # http://example.com/ + example_html = <<~HTML + <body> + <div> + <h1>Example Domain</h1> + <p>This domain is established to be used for illustrative examples in documents. You may use this + domain in examples without prior coordination or asking for permission.</p> + <p><a href="http://www.iana.org/domains/example">More information...</a></p> + </div> + </body> + HTML + script: CGI.escapeHTML(example_html) + loop_count: 1000000 diff --git a/benchmark/class_superclass.yml b/benchmark/class_superclass.yml new file mode 100644 index 0000000000..847ff811f1 --- /dev/null +++ b/benchmark/class_superclass.yml @@ -0,0 +1,23 @@ +prelude: | + class SimpleClass; end + class OneModuleClass + 1.times { include Module.new } + end + class MediumClass + 10.times { include Module.new } + end + class LargeClass + 100.times { include Module.new } + end +benchmark: + object_class_superclass: | + Object.superclass + simple_class_superclass: | + SimpleClass.superclass + one_module_class: | + OneModuleClass.superclass + medium_class_superclass: | + MediumClass.superclass + large_class_superclass: | + LargeClass.superclass +loop_count: 20000000 diff --git a/benchmark/complex_float_add.yml b/benchmark/complex_float_add.yml new file mode 100644 index 0000000000..d0150c5e5b --- /dev/null +++ b/benchmark/complex_float_add.yml @@ -0,0 +1,7 @@ +prelude: | + max, min = 1000.0, -1000.0 + a = Complex(rand(max)+min, rand(max)+min) + b = Complex(rand(max)+min, rand(max)+min) +benchmark: + complex_float_add: c = a + b +loop_count: 1000000 diff --git a/benchmark/complex_float_div.yml b/benchmark/complex_float_div.yml new file mode 100644 index 0000000000..b9f5e1d51c --- /dev/null +++ b/benchmark/complex_float_div.yml @@ -0,0 +1,7 @@ +prelude: | + max, min = 1000.0, -1000.0 + a = Complex(rand(max)+min, rand(max)+min) + b = Complex(rand(max)+min, rand(max)+min) +benchmark: + complex_float_div: c = a / b +loop_count: 1000000 diff --git a/benchmark/complex_float_mul.yml b/benchmark/complex_float_mul.yml new file mode 100644 index 0000000000..59b096a6dc --- /dev/null +++ b/benchmark/complex_float_mul.yml @@ -0,0 +1,7 @@ +prelude: | + max, min = 1000.0, -1000.0 + a = Complex(rand(max)+min, rand(max)+min) + b = Complex(rand(max)+min, rand(max)+min) +benchmark: + complex_float_mul: c = a * b +loop_count: 1000000 diff --git a/benchmark/complex_float_new.yml b/benchmark/complex_float_new.yml new file mode 100644 index 0000000000..6fcde3125b --- /dev/null +++ b/benchmark/complex_float_new.yml @@ -0,0 +1,7 @@ +prelude: | + max, min = 1000.0, -1000.0 + a = Complex(rand(max)+min, rand(max)+min) + b = Complex(rand(max)+min, rand(max)+min) +benchmark: + complex_float_new: c = Complex(a, b) +loop_count: 1000000 diff --git a/benchmark/complex_float_power.yml b/benchmark/complex_float_power.yml new file mode 100644 index 0000000000..c40a31ab55 --- /dev/null +++ b/benchmark/complex_float_power.yml @@ -0,0 +1,7 @@ +prelude: | + max, min = 1000.0, -1000.0 + a = Complex(rand(max)+min, rand(max)+min) + b = Complex(rand(max)+min, rand(max)+min) +benchmark: + complex_float_power: c = a ** b +loop_count: 1000000 diff --git a/benchmark/complex_float_sub.yml b/benchmark/complex_float_sub.yml new file mode 100644 index 0000000000..3fafe7cdbe --- /dev/null +++ b/benchmark/complex_float_sub.yml @@ -0,0 +1,7 @@ +prelude: | + max, min = 1000.0, -1000.0 + a = Complex(rand(max)+min, rand(max)+min) + b = Complex(rand(max)+min, rand(max)+min) +benchmark: + complex_float_sub: c = a - b +loop_count: 1000000 diff --git a/benchmark/constant_invalidation.rb b/benchmark/constant_invalidation.rb new file mode 100644 index 0000000000..a95ec6f37e --- /dev/null +++ b/benchmark/constant_invalidation.rb @@ -0,0 +1,22 @@ +$VERBOSE = nil + +CONSTANT1 = 1 +CONSTANT2 = 1 +CONSTANT3 = 1 +CONSTANT4 = 1 +CONSTANT5 = 1 + +def constants + [CONSTANT1, CONSTANT2, CONSTANT3, CONSTANT4, CONSTANT5] +end + +500_000.times do + constants + + # With previous behavior, this would cause all of the constant caches + # associated with the constant lookups listed above to invalidate, meaning + # they would all have to be fetched again. With current behavior, it only + # invalidates when a name matches, so the following constant set shouldn't + # impact the constant lookups listed above. + INVALIDATE = true +end diff --git a/benchmark/dir_empty_p.rb b/benchmark/dir_empty_p.rb new file mode 100644 index 0000000000..8329c757cf --- /dev/null +++ b/benchmark/dir_empty_p.rb @@ -0,0 +1,5 @@ +require 'tmpdir' +max = 100_000 +Dir.mktmpdir('bm_dir_empty_p') do |dir| + max.times { Dir.empty?(dir) } +end diff --git a/benchmark/driver.rb b/benchmark/driver.rb deleted file mode 100644 index 3904e25503..0000000000 --- a/benchmark/driver.rb +++ /dev/null @@ -1,321 +0,0 @@ -# -# Ruby Benchmark driver -# - -first = true - -begin - require 'optparse' -rescue LoadError - if first - first = false - $:.unshift File.join(File.dirname(__FILE__), '../lib') - retry - else - raise - end -end - -require 'benchmark' -require 'pp' - -class BenchmarkDriver - def self.benchmark(opt) - driver = self.new(opt[:execs], opt[:dir], opt) - begin - driver.run - ensure - driver.show_results - end - end - - def output *args - puts(*args) - @output and @output.puts(*args) - end - - def message *args - output(*args) if @verbose - end - - def message_print *args - if @verbose - print(*args) - STDOUT.flush - @output and @output.print(*args) - end - end - - def progress_message *args - unless STDOUT.tty? - STDERR.print(*args) - STDERR.flush - end - end - - def initialize execs, dir, opt = {} - @execs = execs.map{|e| - e.strip! - next if e.empty? - - if /(.+)::(.+)/ =~ e - # ex) ruby-a::/path/to/ruby-a - label = $1.strip - path = $2 - version = `#{path} -v`.chomp - else - path = e - version = label = `#{path} -v`.chomp - end - [path, label, version] - }.compact - - @dir = dir - @repeat = opt[:repeat] || 1 - @repeat = 1 if @repeat < 1 - @pattern = opt[:pattern] || nil - @exclude = opt[:exclude] || nil - @verbose = opt[:quiet] ? false : (opt[:verbose] || false) - @output = opt[:output] ? open(opt[:output], 'w') : nil - @rawdata_output = opt[:rawdata_output] ? open(opt[:rawdata_output], 'w') : nil - @loop_wl1 = @loop_wl2 = nil - @ruby_arg = opt[:ruby_arg] || nil - @opt = opt - - # [[name, [[r-1-1, r-1-2, ...], [r-2-1, r-2-2, ...]]], ...] - @results = [] - - if @verbose - @start_time = Time.now - message @start_time - @execs.each_with_index{|(path, label, version), i| - message "target #{i}: " + (label == version ? "#{label}" : "#{label} (#{version})") + " at \"#{path}\"" - } - end - end - - def adjusted_results name, results - s = nil - results.each_with_index{|e, i| - r = e.min - case name - when /^vm1_/ - if @loop_wl1 - r -= @loop_wl1[i] - r = 0 if r < 0 - s = '*' - end - when /^vm2_/ - if @loop_wl2 - r -= @loop_wl2[i] - r = 0 if r < 0 - s = '*' - end - end - yield r - } - s - end - - def show_results - output - - if @verbose - message '-----------------------------------------------------------' - message 'raw data:' - message - message PP.pp(@results, "", 79) - message - message "Elapsed time: #{Time.now - @start_time} (sec)" - end - - if @rawdata_output - h = {} - h[:cpuinfo] = File.read('/proc/cpuinfo') if File.exist?('/proc/cpuinfo') - h[:executables] = @execs - h[:results] = @results - @rawdata_output.puts h.inspect - end - - output '-----------------------------------------------------------' - output 'benchmark results:' - - if @verbose and @repeat > 1 - output "minimum results in each #{@repeat} measurements." - end - - output "Execution time (sec)" - output "name\t#{@execs.map{|(_, v)| v}.join("\t")}" - @results.each{|v, result| - rets = [] - s = adjusted_results(v, result){|r| - rets << sprintf("%.3f", r) - } - output "#{v}#{s}\t#{rets.join("\t")}" - } - - if @execs.size > 1 - output - output "Speedup ratio: compare with the result of `#{@execs[0][1]}' (greater is better)" - output "name\t#{@execs[1..-1].map{|(_, v)| v}.join("\t")}" - @results.each{|v, result| - rets = [] - first_value = nil - s = adjusted_results(v, result){|r| - if first_value - if r == 0 - rets << "Error" - else - rets << sprintf("%.3f", first_value/r) - end - else - first_value = r - end - } - output "#{v}#{s}\t#{rets.join("\t")}" - } - end - - if @opt[:output] - output - output "Log file: #{@opt[:output]}" - end - end - - def files - flag = {} - @files = Dir.glob(File.join(@dir, 'bm*.rb')).map{|file| - next if @pattern && /#{@pattern}/ !~ File.basename(file) - next if @exclude && /#{@exclude}/ =~ File.basename(file) - case file - when /bm_(vm[12])_/, /bm_loop_(whileloop2?).rb/ - flag[$1] = true - end - file - }.compact - - if flag['vm1'] && !flag['whileloop'] - @files << File.join(@dir, 'bm_loop_whileloop.rb') - elsif flag['vm2'] && !flag['whileloop2'] - @files << File.join(@dir, 'bm_loop_whileloop2.rb') - end - - @files.sort! - progress_message "total: #{@files.size * @repeat} trial(s) (#{@repeat} trial(s) for #{@files.size} benchmark(s))\n" - @files - end - - def run - files.each_with_index{|file, i| - @i = i - r = measure_file(file) - - if /bm_loop_whileloop.rb/ =~ file - @loop_wl1 = r[1].map{|e| e.min} - elsif /bm_loop_whileloop2.rb/ =~ file - @loop_wl2 = r[1].map{|e| e.min} - end - } - end - - def measure_file file - name = File.basename(file, '.rb').sub(/^bm_/, '') - prepare_file = File.join(File.dirname(file), "prepare_#{name}.rb") - load prepare_file if FileTest.exist?(prepare_file) - - if @verbose - output - output '-----------------------------------------------------------' - output name - output - output File.read(file) - output - end - - result = [name] - result << @execs.map{|(e, v)| - (0...@repeat).map{ - message_print "#{v}\t" - progress_message '.' - - m = measure(e, file) - message "#{m}" - m - } - } - @results << result - result - end - - unless defined?(File::NULL) - if File.exist?('/dev/null') - File::NULL = '/dev/null' - end - end - - def measure executable, file - cmd = "#{executable} #{@ruby_arg} #{file}" - - m = Benchmark.measure{ - system(cmd, out: File::NULL) - } - - if $? != 0 - output "\`#{cmd}\' exited with abnormal status (#{$?})" - 0 - else - m.real - end - end -end - -if __FILE__ == $0 - opt = { - :execs => [], - :dir => File.dirname(__FILE__), - :repeat => 1, - :output => "bmlog-#{Time.now.strftime('%Y%m%d-%H%M%S')}.#{$$}", - :raw_output => nil - } - - parser = OptionParser.new{|o| - o.on('-e', '--executables [EXECS]', - "Specify benchmark one or more targets (e1::path1; e2::path2; e3::path3;...)"){|e| - e.split(/;/).each{|path| - opt[:execs] << path - } - } - o.on('-d', '--directory [DIRECTORY]', "Benchmark suites directory"){|d| - opt[:dir] = d - } - o.on('-p', '--pattern [PATTERN]', "Benchmark name pattern"){|p| - opt[:pattern] = p - } - o.on('-x', '--exclude [PATTERN]', "Benchmark exclude pattern"){|e| - opt[:exclude] = e - } - o.on('-r', '--repeat-count [NUM]', "Repeat count"){|n| - opt[:repeat] = n.to_i - } - o.on('-o', '--output-file [FILE]', "Output file"){|f| - opt[:output] = f - } - o.on('--ruby-arg [ARG]', "Optional argument for ruby"){|a| - opt[:ruby_arg] = a - } - o.on('--rawdata-output [FILE]', 'output rawdata'){|r| - opt[:rawdata_output] = r - } - o.on('-v', '--verbose'){|v| - opt[:verbose] = v - } - o.on('-q', '--quiet', "Run without notify information except result table."){|q| - opt[:quiet] = q - opt[:verbose] = false - } - } - - parser.parse!(ARGV) - BenchmarkDriver.benchmark(opt) -end - diff --git a/benchmark/enum_lazy_flat_map.yml b/benchmark/enum_lazy_flat_map.yml new file mode 100644 index 0000000000..0ee390a441 --- /dev/null +++ b/benchmark/enum_lazy_flat_map.yml @@ -0,0 +1,16 @@ +prelude: | + num = (1..).lazy.take(100) + ary2 = [[1,2]].cycle.lazy.take(10) + ary10 = [[*1..10]].cycle.lazy.take(10) + ary20 = [[*1..20]].cycle.lazy.take(10) + ary50 = [[*1..50]].cycle.lazy.take(10) + ary100 = [[*1..100]].cycle.lazy.take(10) + +benchmark: + num3: num.flat_map {|x| x}.take(3).to_a + num10: num.flat_map {|x| x}.take(3).to_a + ary2: ary2.flat_map {|x| x}.take(3).to_a + ary10: ary10.flat_map {|x| x}.take(3).to_a + ary20: ary20.flat_map {|x| x}.take(3).to_a + ary50: ary50.flat_map {|x| x}.take(3).to_a + ary100: ary100.flat_map {|x| x}.take(3).to_a diff --git a/benchmark/enum_lazy_grep_v_100.rb b/benchmark/enum_lazy_grep_v_100.rb new file mode 100644 index 0000000000..8832392e65 --- /dev/null +++ b/benchmark/enum_lazy_grep_v_100.rb @@ -0,0 +1,4 @@ +grep_data = (1..10).to_a * 1000 +N = 100 +enum = grep_data.lazy.grep_v(->(i){i == 0}).grep_v(->(i){i == 0}) +N.times {enum.each {}} diff --git a/benchmark/enum_lazy_grep_v_20.rb b/benchmark/enum_lazy_grep_v_20.rb new file mode 100644 index 0000000000..329509fa8f --- /dev/null +++ b/benchmark/enum_lazy_grep_v_20.rb @@ -0,0 +1,4 @@ +grep_data = (1..10).to_a * 1000 +N = 100 +enum = grep_data.lazy.grep_v(->(i){i > 2}).grep_v(->(i){i > 2}) +N.times {enum.each {}} diff --git a/benchmark/enum_lazy_grep_v_50.rb b/benchmark/enum_lazy_grep_v_50.rb new file mode 100644 index 0000000000..02ea4d4e71 --- /dev/null +++ b/benchmark/enum_lazy_grep_v_50.rb @@ -0,0 +1,4 @@ +grep_data = (1..10).to_a * 1000 +N = 100 +enum = grep_data.lazy.grep_v(->(i){i > 5}).grep_v(->(i){i > 5}) +N.times {enum.each {}} diff --git a/benchmark/enum_lazy_uniq_100.rb b/benchmark/enum_lazy_uniq_100.rb new file mode 100644 index 0000000000..2e6434d9c4 --- /dev/null +++ b/benchmark/enum_lazy_uniq_100.rb @@ -0,0 +1,4 @@ +uniq_data = (1..10_000).to_a +N = 100 +enum = uniq_data.lazy.uniq {|i| i % 10000}.uniq {|i| i % 10000} +N.times {enum.each {}} diff --git a/benchmark/enum_lazy_uniq_20.rb b/benchmark/enum_lazy_uniq_20.rb new file mode 100644 index 0000000000..75e6398fee --- /dev/null +++ b/benchmark/enum_lazy_uniq_20.rb @@ -0,0 +1,4 @@ +uniq_data = (1..10_000).to_a +N = 100 +enum = uniq_data.lazy.uniq {|i| i % 2000}.uniq {|i| i % 2000} +N.times {enum.each {}} diff --git a/benchmark/enum_lazy_uniq_50.rb b/benchmark/enum_lazy_uniq_50.rb new file mode 100644 index 0000000000..59a39b78ff --- /dev/null +++ b/benchmark/enum_lazy_uniq_50.rb @@ -0,0 +1,4 @@ +uniq_data = (1..10_000).to_a +N = 100 +enum = uniq_data.lazy.uniq {|i| i % 5000}.uniq {|i| i % 5000} +N.times {enum.each {}} diff --git a/benchmark/enum_lazy_zip.yml b/benchmark/enum_lazy_zip.yml new file mode 100644 index 0000000000..4566ff0261 --- /dev/null +++ b/benchmark/enum_lazy_zip.yml @@ -0,0 +1,22 @@ +prelude: | + a = (1..3).lazy + b = a.map {|x| x} + +benchmark: + first_ary: a.zip(["a", "b", "c"]).first + first_nonary: a.zip("a".."c").first + first_noarg: a.zip.first + + take3_ary: a.zip(["a", "b", "c"]).take(3).force + take3_nonary: a.zip("a".."c").take(3).force + take3_noarg: a.zip.take(3).force + + chain-first_ary: b.zip(["a", "b", "c"]).first + chain-first_nonary: b.zip("a".."c").first + chain-first_noarg: b.zip.first + + chain-take3_ary: b.zip(["a", "b", "c"]).take(3).force + chain-take3_nonary: b.zip("a".."c").take(3).force + chain-take3_noarg: b.zip.take(3).force + + block: a.zip("a".."c") {|x, y| [x, y]} diff --git a/benchmark/enum_minmax.yml b/benchmark/enum_minmax.yml new file mode 100644 index 0000000000..9d01731abb --- /dev/null +++ b/benchmark/enum_minmax.yml @@ -0,0 +1,25 @@ +prelude: | + set2 = 2.times.to_a.shuffle.to_set + set10 = 10.times.to_a.shuffle.to_set + set100 = 100.times.to_a.shuffle.to_set + set1000 = 1000.times.to_a.shuffle.to_set + set10000 = 10000.times.to_a.shuffle.to_set + +benchmark: + set2.min: set2.min + set10.min: set10.min + set100.min: set100.min + set1000.min: set1000.min + set10000.min: set10000.min + set2.max: set2.max + set10.max: set10.max + set100.max: set100.max + set1000.max: set1000.max + set10000.max: set10000.max + set2.minmax: set2.minmax + set10.minmax: set10.minmax + set100.minmax: set100.minmax + set1000.minmax: set1000.minmax + set10000.minmax: set10000.minmax + +loop_count: 10000 diff --git a/benchmark/enum_sort.yml b/benchmark/enum_sort.yml new file mode 100644 index 0000000000..6f26e748c6 --- /dev/null +++ b/benchmark/enum_sort.yml @@ -0,0 +1,15 @@ +prelude: | + set2 = 2.times.to_a.shuffle.to_set + set10 = 10.times.to_a.shuffle.to_set + set100 = 100.times.to_a.shuffle.to_set + set1000 = 1000.times.to_a.shuffle.to_set + set10000 = 10000.times.to_a.shuffle.to_set + +benchmark: + set2.sort_by: set2.sort_by { 0 } + set10.sort_by: set10.sort_by { 0 } + set100.sort_by: set100.sort_by { 0 } + set1000.sort_by: set1000.sort_by { 0 } + set10000.sort_by: set10000.sort_by { 0 } + +loop_count: 10000 diff --git a/benchmark/enum_sort_by.yml b/benchmark/enum_sort_by.yml new file mode 100644 index 0000000000..d386353888 --- /dev/null +++ b/benchmark/enum_sort_by.yml @@ -0,0 +1,53 @@ +prelude: | + array_length = 2 + fixnum_array2 = array_length.times.to_a.map {rand(10000)} + float_array2 = array_length.times.to_a.map {rand(10000.0).to_f} + string_array2 = array_length.times.to_a.map {"r" * rand(1..10000)} + mix_array2 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} + all_zero_array2 =array_length.times.to_a.map {0} + + array_length = 10 + fixnum_array10 = array_length.times.to_a.map {rand(10000)} + float_array10 = array_length.times.to_a.map {rand(10000.0).to_f} + string_array10 = array_length.times.to_a.map {"r" * rand(1..10000)} + mix_array10 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} + all_zero_array10 =array_length.times.to_a.map {0} + + array_length = 1000 + fixnum_array1000 = array_length.times.to_a.map {rand(10000)} + float_array1000 = array_length.times.to_a.map {rand(10000.0).to_f} + string_array1000 = array_length.times.to_a.map {"r" * rand(1..10000)} + mix_array1000 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} + all_zero_array1000 =array_length.times.to_a.map {0} + + array_length = 100000 + fixnum_array100000 = array_length.times.to_a.map {rand(10000)} + float_array100000 = array_length.times.to_a.map {rand(10000.0).to_f} + string_array100000 = array_length.times.to_a.map {"r" * rand(1..10000)} + mix_array100000 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} + all_zero_array100000 =array_length.times.to_a.map {0} + +benchmark: + fixnum_array2.sort_by: fixnum_array2.sort_by {|a| a} + float_array2.sort_by: float_array2.sort_by {|a| a} + string_length2.sort_by: string_array2.sort_by {|a| a.length} + mix_array2.sort_by: mix_array2.sort_by {|a| a} + all_zero2.sort_by: all_zero_array2.sort_by{|a| a} + + fixnum_array10.sort_by: fixnum_array10.sort_by {|a| a} + float_array10.sort_by: float_array10.sort_by {|a| a} + string_length10.sort_by: string_array10.sort_by {|a| a.length} + mix_array10.sort_by: mix_array10.sort_by {|a| a} + all_zero10.sort_by: all_zero_array10.sort_by{|a| a} + + fixnum_array1000.sort_by: fixnum_array1000.sort_by {|a| a} + float_array1000.sort_by: float_array1000.sort_by {|a| a} + string_length1000.sort_by: string_array1000.sort_by {|a| a.length} + mix_array1000.sort_by: mix_array1000.sort_by {|a| a} + all_zero1000.sort_by: all_zero_array1000.sort_by{|a| a} + + fixnum_array100000.sort_by: fixnum_array100000.sort_by {|a| a} + float_array100000.sort_by: float_array100000.sort_by {|a| a} + string_length100000.sort_by: string_array100000.sort_by {|a| a.length} + mix_array100000.sort_by: mix_array100000.sort_by {|a| a} + all_zero100000.sort_by: all_zero_array100000.sort_by{|a| a} diff --git a/benchmark/enum_tally.yml b/benchmark/enum_tally.yml new file mode 100644 index 0000000000..edd2e040a0 --- /dev/null +++ b/benchmark/enum_tally.yml @@ -0,0 +1,4 @@ +prelude: | + list = ("aaa".."zzz").to_a*10 +benchmark: + tally: list.tally diff --git a/benchmark/erb_escape_html.yml b/benchmark/erb_escape_html.yml new file mode 100644 index 0000000000..ca28d756e7 --- /dev/null +++ b/benchmark/erb_escape_html.yml @@ -0,0 +1,31 @@ +prelude: | + # frozen_string_literal: true + require 'erb' +benchmark: + - script: ERB::Util.html_escape("") + loop_count: 20000000 + - script: ERB::Util.html_escape("abcde") + loop_count: 20000000 + - script: ERB::Util.html_escape("abcd<") + loop_count: 20000000 + - script: ERB::Util.html_escape("'&\"<>") + loop_count: 5000000 + - prelude: long_no_escape = "abcde" * 300 + script: ERB::Util.html_escape(long_no_escape) + loop_count: 1000000 + - prelude: long_all_escape = "'&\"<>" * 10 + script: ERB::Util.html_escape(long_all_escape) + loop_count: 1000000 + - prelude: | # http://example.com/ + example_html = <<~HTML + <body> + <div> + <h1>Example Domain</h1> + <p>This domain is established to be used for illustrative examples in documents. You may use this + domain in examples without prior coordination or asking for permission.</p> + <p><a href="http://www.iana.org/domains/example">More information...</a></p> + </div> + </body> + HTML + script: ERB::Util.html_escape(example_html) + loop_count: 1000000 diff --git a/benchmark/erb_render.yml b/benchmark/erb_render.yml new file mode 100644 index 0000000000..15f6c3880b --- /dev/null +++ b/benchmark/erb_render.yml @@ -0,0 +1,24 @@ +prelude: | + require 'erb' + + data = <<erb + <html> + <head> <%= title %> </head> + <body> + <h1> <%= title %> </h1> + <p> + <%= content %> + </p> + </body> + </html> + erb + + title = "hello world!" + content = "hello world!\n" * 10 + + src = "def self.render(title, content); #{ERB.new(data).src}; end" + mod = Module.new + mod.instance_eval(src, "(ERB)") +benchmark: + erb_render: mod.render(title, content) +loop_count: 1500000 diff --git a/benchmark/fiber_chain.yml b/benchmark/fiber_chain.yml new file mode 100644 index 0000000000..a36c759f8e --- /dev/null +++ b/benchmark/fiber_chain.yml @@ -0,0 +1,36 @@ +prelude: | + def make_link(previous) + Fiber.new do + while message = previous.resume + Fiber.yield(message) + end + end + end + + def make_chain(length = 1000, &block) + chain = Fiber.new(&block) + + (length - 1).times do + chain = make_link(chain) + end + + return chain + end + + message = "Hello World!" + + chain = make_chain do + while true + Fiber.yield(message) + end + end +benchmark: + make_chain: | + make_chain(100) do + while true + Fiber.yield(message) + end + end + resume_chain: | + chain.resume +loop_count: 5000 diff --git a/benchmark/fiber_locals.yml b/benchmark/fiber_locals.yml new file mode 100644 index 0000000000..8588686477 --- /dev/null +++ b/benchmark/fiber_locals.yml @@ -0,0 +1,8 @@ +prelude: | + th = Thread.current + th[:key] = :val +benchmark: + key?: th.key?(:key) + []: th[:key] + keys: th.keys +loop_count: 1_000_000 diff --git a/benchmark/file_basename.yml b/benchmark/file_basename.yml new file mode 100644 index 0000000000..fbd78785aa --- /dev/null +++ b/benchmark/file_basename.yml @@ -0,0 +1,6 @@ +prelude: | + # frozen_string_literal: true +benchmark: + long: File.basename("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml") + long_name: File.basename("Users_george_src_github.com_ruby_ruby_benchmark_file_dirname.yml") + withext: File.basename("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml", ".yml") diff --git a/benchmark/file_chmod.rb b/benchmark/file_chmod.rb new file mode 100644 index 0000000000..1cd4760c9d --- /dev/null +++ b/benchmark/file_chmod.rb @@ -0,0 +1,9 @@ +# chmod file +require 'tempfile' +max = 200_000 +tmp = Tempfile.new('chmod') +path = tmp.path +max.times do + File.chmod(0777, path) +end +tmp.close! diff --git a/benchmark/file_dirname.yml b/benchmark/file_dirname.yml new file mode 100644 index 0000000000..43a81c9371 --- /dev/null +++ b/benchmark/file_dirname.yml @@ -0,0 +1,6 @@ +prelude: | + # frozen_string_literal: true +benchmark: + long: File.dirname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml") + short: File.dirname("foo/bar") + n_4: File.dirname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml", 4) diff --git a/benchmark/file_extname.yml b/benchmark/file_extname.yml new file mode 100644 index 0000000000..fb16e55840 --- /dev/null +++ b/benchmark/file_extname.yml @@ -0,0 +1,6 @@ +prelude: | + # frozen_string_literal: true +benchmark: + long: File.extname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml") + long_name: File.extname("Users_george_src_github.com_ruby_ruby_benchmark_file_dirname.yml") + short: File.extname("foo/bar") diff --git a/benchmark/file_join.yml b/benchmark/file_join.yml new file mode 100644 index 0000000000..845257cf1e --- /dev/null +++ b/benchmark/file_join.yml @@ -0,0 +1,7 @@ +prelude: | + # frozen_string_literal: true +benchmark: + two_strings: File.join(__FILE__, "path") + many_strings: File.join(__FILE__, "path", "a", "b", "c", "d") + array: File.join([__FILE__, "path", "a", "b", "c", "d"]) + mixed: File.join(__FILE__, "path", "a", "b", ["c", "d"]) diff --git a/benchmark/file_rename.rb b/benchmark/file_rename.rb new file mode 100644 index 0000000000..bbb44aebac --- /dev/null +++ b/benchmark/file_rename.rb @@ -0,0 +1,11 @@ +# rename file +require 'tempfile' + +max = 100_000 +tmp = [ Tempfile.new('rename-a'), Tempfile.new('rename-b') ] +a, b = tmp.map { |x| x.path } +tmp.each { |t| t.close } # Windows can't rename files without closing them +max.times do + File.rename(a, b) + File.rename(b, a) +end diff --git a/benchmark/float_methods.yml b/benchmark/float_methods.yml new file mode 100644 index 0000000000..56ea41effc --- /dev/null +++ b/benchmark/float_methods.yml @@ -0,0 +1,14 @@ +prelude: | + flo = 4.2 +benchmark: + to_f: | + flo.to_f + abs: | + flo.abs + magnitude: | + flo.magnitude + -@: | + -flo + zero?: | + flo.zero? +loop_count: 20000000 diff --git a/benchmark/float_neg_posi.yml b/benchmark/float_neg_posi.yml new file mode 100644 index 0000000000..172db1bf6d --- /dev/null +++ b/benchmark/float_neg_posi.yml @@ -0,0 +1,8 @@ +prelude: | + flo = 4.2 +benchmark: + negative?: | + flo.negative? + positive?: | + flo.positive? +loop_count: 20000000 diff --git a/benchmark/float_to_s.yml b/benchmark/float_to_s.yml new file mode 100644 index 0000000000..0abae5cdb8 --- /dev/null +++ b/benchmark/float_to_s.yml @@ -0,0 +1,7 @@ +prelude: | + floats = [*0.0.step(1.0, 0.0001)] + +benchmark: + to_s: floats.each {|f| f.to_s} + +loop_count: 1000 diff --git a/benchmark/gc/aobench.rb b/benchmark/gc/aobench.rb index 2eed7abc83..275f58b924 100644 --- a/benchmark/gc/aobench.rb +++ b/benchmark/gc/aobench.rb @@ -1 +1 @@ -require_relative '../bm_app_aobench.rb' +require_relative '../app_aobench' diff --git a/benchmark/gc/binary_trees.rb b/benchmark/gc/binary_trees.rb index af8ea722aa..83347cdd20 100644 --- a/benchmark/gc/binary_trees.rb +++ b/benchmark/gc/binary_trees.rb @@ -1 +1 @@ -require_relative '../bm_so_binary_trees.rb' +require_relative '../so_binary_trees' diff --git a/benchmark/gc/gcbench.rb b/benchmark/gc/gcbench.rb index 09a404466a..23d0b91c6c 100644 --- a/benchmark/gc/gcbench.rb +++ b/benchmark/gc/gcbench.rb @@ -3,11 +3,12 @@ require 'pp' require 'optparse' $list = true -$gcprof = true +$gcprof = false opt = OptionParser.new opt.on('-q'){$list = false} opt.on('-d'){$gcprof = false} +opt.on('-p'){$gcprof = true} opt.parse!(ARGV) script = File.join(File.dirname(__FILE__), ARGV.shift) diff --git a/benchmark/gc/pentomino.rb b/benchmark/gc/pentomino.rb index 94ba74be89..8ebdff7d1d 100644 --- a/benchmark/gc/pentomino.rb +++ b/benchmark/gc/pentomino.rb @@ -1 +1 @@ -require_relative '../bm_app_pentomino.rb' +require_relative '../app_pentomino' diff --git a/benchmark/hash_aref_array.rb b/benchmark/hash_aref_array.rb new file mode 100644 index 0000000000..ac7a683d95 --- /dev/null +++ b/benchmark/hash_aref_array.rb @@ -0,0 +1,5 @@ +h = {} +arrays = (0..99).each_slice(10).to_a +#STDERR.puts arrays.inspect +arrays.each { |s| h[s] = s } +200_000.times { arrays.each { |s| h[s] } } diff --git a/benchmark/hash_aref_dsym.rb b/benchmark/hash_aref_dsym.rb new file mode 100644 index 0000000000..af4f8c36d4 --- /dev/null +++ b/benchmark/hash_aref_dsym.rb @@ -0,0 +1,4 @@ +h = {} +syms = ('a'..'z').map { |s| s.to_sym } +syms.each { |s| h[s] = 1 } +200_000.times { syms.each { |s| h[s] } } diff --git a/benchmark/hash_aref_dsym_long.rb b/benchmark/hash_aref_dsym_long.rb new file mode 100644 index 0000000000..9d7759379e --- /dev/null +++ b/benchmark/hash_aref_dsym_long.rb @@ -0,0 +1,21 @@ +# [ruby-core:70129] [Bug #11396] +collection_size = 200000 +sample_size = 10000 + +values = (1..collection_size).to_a.map do |x| + "THIS IS A LONGER STRING THAT IS ALSO UNIQUE #{x}" +end + +symbol_hash = {} + +values.each do |x| + symbol_hash[x.to_sym] = 1 +end + +# use the same samples each time to minimize deviations +rng = Random.new(0) +symbol_sample_array = values.sample(sample_size, random: rng).map(&:to_sym) + +3000.times do + symbol_sample_array.each { |x| symbol_hash[x] } +end diff --git a/benchmark/hash_aref_fix.rb b/benchmark/hash_aref_fix.rb new file mode 100644 index 0000000000..1346890582 --- /dev/null +++ b/benchmark/hash_aref_fix.rb @@ -0,0 +1,4 @@ +h = {} +nums = (1..26).to_a +nums.each { |i| h[i] = i } +200_000.times { nums.each { |s| h[s] } } diff --git a/benchmark/hash_aref_flo.rb b/benchmark/hash_aref_flo.rb new file mode 100644 index 0000000000..2217274c82 --- /dev/null +++ b/benchmark/hash_aref_flo.rb @@ -0,0 +1,4 @@ +h = {} +strs = [*1..10000].map! {|i| i.fdiv(10)} +strs.each { |s| h[s] = s } +50.times { strs.each { |s| h[s] } } diff --git a/benchmark/bm_hash_aref_miss.rb b/benchmark/hash_aref_miss.rb index b0913dd4bb..b0913dd4bb 100644 --- a/benchmark/bm_hash_aref_miss.rb +++ b/benchmark/hash_aref_miss.rb diff --git a/benchmark/bm_hash_aref_str.rb b/benchmark/hash_aref_str.rb index 19439b061b..19439b061b 100644 --- a/benchmark/bm_hash_aref_str.rb +++ b/benchmark/hash_aref_str.rb diff --git a/benchmark/hash_aref_str_lit.yml b/benchmark/hash_aref_str_lit.yml new file mode 100644 index 0000000000..ed8142bcf1 --- /dev/null +++ b/benchmark/hash_aref_str_lit.yml @@ -0,0 +1,20 @@ +prelude: | + # frozen_string_literal: true + hash = 10.times.to_h do |i| + [i, i] + end + dyn_sym = "dynamic_symbol".to_sym + binary = RubyVM::InstructionSequence.compile("# frozen_string_literal: true\n'iseq_load'").to_binary + iseq_literal_string = RubyVM::InstructionSequence.load_from_binary(binary).eval + + hash[:some_symbol] = 1 + hash[dyn_sym] = 2 + hash["small"] = 3 + hash["frozen_string_literal"] = 4 + hash[iseq_literal_string] = 5 +benchmark: + symbol: hash[:some_symbol] + dyn_symbol: hash[dyn_sym] + small_lit: hash["small"] + frozen_lit: hash["frozen_string_literal"] + iseq_lit: hash[iseq_literal_string] diff --git a/benchmark/hash_aref_sym.rb b/benchmark/hash_aref_sym.rb new file mode 100644 index 0000000000..f75d163fe6 --- /dev/null +++ b/benchmark/hash_aref_sym.rb @@ -0,0 +1,9 @@ +h = {} +syms = ('a'..'z').to_a +begin + syms = eval("%i[#{syms.join(' ')}]") +rescue SyntaxError # <= 1.9.3 + syms.map!(&:to_sym) +end +syms.each { |s| h[s] = s } +200_000.times { syms.each { |s| h[s] } } diff --git a/benchmark/bm_hash_aref_sym_long.rb b/benchmark/hash_aref_sym_long.rb index a9be4059e6..9dab8df7be 100644 --- a/benchmark/bm_hash_aref_sym_long.rb +++ b/benchmark/hash_aref_sym_long.rb @@ -3,6 +3,11 @@ syms = %w[puts warn syswrite write stat bacon lettuce tomato some symbols in this array may already be interned others should not be hash browns make good breakfast but not cooked using prime numbers shift for division entries delete_if keys exist? -].map!(&:to_sym) +] +begin + syms = eval("%i[#{syms.join(' ')}]") +rescue SyntaxError # <= 1.9.3 + syms.map!(&:to_sym) +end syms.each { |s| h[s] = s } 200_000.times { syms.each { |s| h[s] } } diff --git a/benchmark/hash_defaults.yml b/benchmark/hash_defaults.yml new file mode 100644 index 0000000000..833f10e1c7 --- /dev/null +++ b/benchmark/hash_defaults.yml @@ -0,0 +1,6 @@ +prelude: | + h = Hash.new { :foo } +benchmark: + default_aref: h[1] + default_method: h.default(1) +loop_count: 1000000 diff --git a/benchmark/hash_dup.yml b/benchmark/hash_dup.yml new file mode 100644 index 0000000000..65f521ec94 --- /dev/null +++ b/benchmark/hash_dup.yml @@ -0,0 +1,8 @@ +prelude: | + small_hash = { a: 1 } + larger_hash = 20.times.map { |i| [('a'.ord + i).chr.to_sym, i] }.to_h + +benchmark: + dup_small: small_hash.dup + dup_larger: larger_hash.dup +loop_count: 10000 diff --git a/benchmark/hash_first.yml b/benchmark/hash_first.yml new file mode 100644 index 0000000000..c26df1a7ed --- /dev/null +++ b/benchmark/hash_first.yml @@ -0,0 +1,11 @@ +prelude: | + hash1 = 1_000_000.times.to_h { [rand, true]} + hash2 = hash1.dup + hash2.keys[1..100_000].each { hash2.delete _1 } + hash2.delete hash2.first[0] + +benchmark: + hash1: hash1.first + hash2: hash2.first + +loop_count: 100_000 diff --git a/benchmark/bm_hash_flatten.rb b/benchmark/hash_flatten.rb index e944aae9f2..e944aae9f2 100644 --- a/benchmark/bm_hash_flatten.rb +++ b/benchmark/hash_flatten.rb diff --git a/benchmark/hash_ident_flo.rb b/benchmark/hash_ident_flo.rb new file mode 100644 index 0000000000..0c7edfed3e --- /dev/null +++ b/benchmark/hash_ident_flo.rb @@ -0,0 +1,4 @@ +h = {}.compare_by_identity +strs = (1..10000).to_a.map!(&:to_f) +strs.each { |s| h[s] = s } +50.times { strs.each { |s| h[s] } } diff --git a/benchmark/bm_hash_ident_num.rb b/benchmark/hash_ident_num.rb index b226736c6f..b226736c6f 100644 --- a/benchmark/bm_hash_ident_num.rb +++ b/benchmark/hash_ident_num.rb diff --git a/benchmark/bm_hash_ident_obj.rb b/benchmark/hash_ident_obj.rb index 4b3b58edec..4b3b58edec 100644 --- a/benchmark/bm_hash_ident_obj.rb +++ b/benchmark/hash_ident_obj.rb diff --git a/benchmark/bm_hash_ident_str.rb b/benchmark/hash_ident_str.rb index 8582b38e31..8582b38e31 100644 --- a/benchmark/bm_hash_ident_str.rb +++ b/benchmark/hash_ident_str.rb diff --git a/benchmark/bm_hash_ident_sym.rb b/benchmark/hash_ident_sym.rb index 4c81e3d28e..4c81e3d28e 100644 --- a/benchmark/bm_hash_ident_sym.rb +++ b/benchmark/hash_ident_sym.rb diff --git a/benchmark/hash_key.yml b/benchmark/hash_key.yml new file mode 100644 index 0000000000..cab4cf9ca4 --- /dev/null +++ b/benchmark/hash_key.yml @@ -0,0 +1,5 @@ +prelude: | + obj = Object.new + hash = { obj => true } +benchmark: hash.key?(obj) +loop_count: 30000000 diff --git a/benchmark/bm_hash_keys.rb b/benchmark/hash_keys.rb index 6863cd01f9..6863cd01f9 100644 --- a/benchmark/bm_hash_keys.rb +++ b/benchmark/hash_keys.rb diff --git a/benchmark/hash_literal_small2.rb b/benchmark/hash_literal_small2.rb new file mode 100644 index 0000000000..c188529260 --- /dev/null +++ b/benchmark/hash_literal_small2.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +1_000_000.times.map { { "foo" => "bar", "bar" => "baz" } } diff --git a/benchmark/hash_literal_small4.rb b/benchmark/hash_literal_small4.rb new file mode 100644 index 0000000000..739f71b5b0 --- /dev/null +++ b/benchmark/hash_literal_small4.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +1_000_000.times.map { { "foo" => "bar", "bar" => "baz", "baz" => "lol", "lol" => "lgtm" } } diff --git a/benchmark/hash_literal_small8.rb b/benchmark/hash_literal_small8.rb new file mode 100644 index 0000000000..53d80af535 --- /dev/null +++ b/benchmark/hash_literal_small8.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +1_000_000.times.map { { "foo" => "bar", "bar" => "baz", "baz" => "lol", "lol" => "lgtm", "lgtm" => "nope", "nope" => "ok", "ok" => "again", "again" => "wait" } } diff --git a/benchmark/hash_long.rb b/benchmark/hash_long.rb new file mode 100644 index 0000000000..03d9109602 --- /dev/null +++ b/benchmark/hash_long.rb @@ -0,0 +1,4 @@ +k1 = "Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong"; +k2 = "Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping"; +h = {k1 => 0, k2 => 0}; +3000000.times{|i| k = i % 2 ? k2 : k1; h [k] = h[k] + 1} diff --git a/benchmark/hash_new.yml b/benchmark/hash_new.yml new file mode 100644 index 0000000000..9d8e34187f --- /dev/null +++ b/benchmark/hash_new.yml @@ -0,0 +1,16 @@ +prelude: | + has_hash_with_capa = Hash.instance_method(:initialize).parameters.include?([:key, :capacity]) + strings_1k = 1_000.times.map { |i| -i.to_s.freeze } + strings_100k = 100_000.times.map { |i| -i.to_s.freeze } +benchmark: + new: Hash.new + new_with_capa_1k: | + h = has_hash_with_capa ? Hash.new(capacity: strings_1k.size) : {} + strings_1k.each do |x| + h[x] = true + end + new_with_capa_100k: | + h = has_hash_with_capa ? Hash.new(capacity: strings_100k.size) : {} + strings_100k.each do |x| + h[x] = true + end diff --git a/benchmark/bm_hash_shift.rb b/benchmark/hash_shift.rb index a645671a5b..a645671a5b 100644 --- a/benchmark/bm_hash_shift.rb +++ b/benchmark/hash_shift.rb diff --git a/benchmark/hash_shift_u16.rb b/benchmark/hash_shift_u16.rb new file mode 100644 index 0000000000..ec800d0342 --- /dev/null +++ b/benchmark/hash_shift_u16.rb @@ -0,0 +1,10 @@ +h = {} + +(16384..65536).each do |i| + h[i] = nil +end + +300000.times do + k, v = h.shift + h[k] = v +end diff --git a/benchmark/hash_shift_u24.rb b/benchmark/hash_shift_u24.rb new file mode 100644 index 0000000000..de4e0fa696 --- /dev/null +++ b/benchmark/hash_shift_u24.rb @@ -0,0 +1,10 @@ +h = {} + +(0xff4000..0xffffff).each do |i| + h[i] = nil +end + +300000.times do + k, v = h.shift + h[k] = v +end diff --git a/benchmark/hash_shift_u32.rb b/benchmark/hash_shift_u32.rb new file mode 100644 index 0000000000..656aa55583 --- /dev/null +++ b/benchmark/hash_shift_u32.rb @@ -0,0 +1,10 @@ +h = {} + +(0xffff4000..0xffffffff).each do |i| + h[i] = nil +end + +300000.times do + k, v = h.shift + h[k] = v +end diff --git a/benchmark/hash_small2.rb b/benchmark/hash_small2.rb new file mode 100644 index 0000000000..45485d9c71 --- /dev/null +++ b/benchmark/hash_small2.rb @@ -0,0 +1 @@ +1000000.times.map{|i| a={}; 2.times{|j| a[j]=j}; a} diff --git a/benchmark/hash_small4.rb b/benchmark/hash_small4.rb new file mode 100644 index 0000000000..acd4084334 --- /dev/null +++ b/benchmark/hash_small4.rb @@ -0,0 +1 @@ +1000000.times.map{|i| a={}; 4.times{|j| a[j]=j}; a} diff --git a/benchmark/hash_small8.rb b/benchmark/hash_small8.rb new file mode 100644 index 0000000000..9cffcc91b6 --- /dev/null +++ b/benchmark/hash_small8.rb @@ -0,0 +1 @@ +1000000.times.map{|i| a={}; 8.times{|j| a[j]=j}; a} diff --git a/benchmark/hash_to_proc.rb b/benchmark/hash_to_proc.rb new file mode 100644 index 0000000000..2b675bf509 --- /dev/null +++ b/benchmark/hash_to_proc.rb @@ -0,0 +1,9 @@ +h = {} + +10000.times do |i| + h[i] = nil +end + +5000.times do |i| + [i].map(&h) +end diff --git a/benchmark/bm_hash_values.rb b/benchmark/hash_values.rb index 069441302f..069441302f 100644 --- a/benchmark/bm_hash_values.rb +++ b/benchmark/hash_values.rb diff --git a/benchmark/int_quo.rb b/benchmark/int_quo.rb new file mode 100644 index 0000000000..e22a3f8c30 --- /dev/null +++ b/benchmark/int_quo.rb @@ -0,0 +1 @@ +5000000.times { 42.quo(3) } diff --git a/benchmark/io_close.yml b/benchmark/io_close.yml new file mode 100644 index 0000000000..a552872884 --- /dev/null +++ b/benchmark/io_close.yml @@ -0,0 +1,13 @@ +prelude: | + ios = 1000.times.map do + 100.times.map{IO.pipe} + end +benchmark: + # Close IO + io_close: | + # Process each batch of ios per iteration of the benchmark. + ios.pop.each do |r, w| + r.close + w.close + end +loop_count: 100 diff --git a/benchmark/io_close_contended.yml b/benchmark/io_close_contended.yml new file mode 100644 index 0000000000..1d9e4e0d0f --- /dev/null +++ b/benchmark/io_close_contended.yml @@ -0,0 +1,21 @@ +prelude: | + ios = 100.times.map do + 10.times.map do + pipe = IO.pipe.tap do |r, w| + Thread.new do + r.read + rescue IOError + # Ignore + end + end + end + end +benchmark: + # Close IO + io_close_contended: | + # Process each batch of ios per iteration of the benchmark. + ios.pop.each do |r, w| + r.close + w.close + end +loop_count: 10 diff --git a/benchmark/io_copy_stream_write.rb b/benchmark/io_copy_stream_write.rb new file mode 100644 index 0000000000..3fd87250a4 --- /dev/null +++ b/benchmark/io_copy_stream_write.rb @@ -0,0 +1,24 @@ +# The goal of this is to use a synthetic (non-IO) reader +# to trigger the read/write loop of IO.copy_stream, +# bypassing in-kernel mechanisms like sendfile for zero copy, +# so we wrap the /dev/zero IO object: + +class Zero + def initialize + @n = 100000 + @in = File.open('/dev/zero', 'rb') + end + + def read(len, buf) + return if (@n -= 1) == 0 + @in.read(len, buf) + end +end + +begin + src = Zero.new + dst = File.open(IO::NULL, 'wb') + n = IO.copy_stream(src, dst) +rescue Errno::ENOENT + # not *nix +end if IO.respond_to?(:copy_stream) && IO.const_defined?(:NULL) diff --git a/benchmark/io_copy_stream_write_socket.rb b/benchmark/io_copy_stream_write_socket.rb new file mode 100644 index 0000000000..11f369bd0d --- /dev/null +++ b/benchmark/io_copy_stream_write_socket.rb @@ -0,0 +1,35 @@ +# The goal of this is to use a synthetic (non-IO) reader +# to trigger the read/write loop of IO.copy_stream, +# bypassing in-kernel mechanisms like sendfile for zero copy, +# so we wrap the /dev/zero IO object: +class Zero + def initialize + @n = 100000 + @in = File.open('/dev/zero', 'rb') + end + + def read(len, buf) + return if (@n -= 1) == 0 + @in.read(len, buf) + end +end + +begin + require 'socket' + src = Zero.new + rd, wr = UNIXSocket.pair + pid = fork do + wr.close + buf = String.new + while rd.read(16384, buf) + end + end + rd.close + IO.copy_stream(src, wr) +rescue Errno::ENOENT, NotImplementedError, NameError + # not *nix: missing /dev/zero, fork, or UNIXSocket +rescue LoadError # no socket? +ensure + wr.close if wr + Process.waitpid(pid) if pid +end if IO.respond_to?(:copy_stream) diff --git a/benchmark/bm_io_file_create.rb b/benchmark/io_file_create.rb index 2f205c1333..2f205c1333 100644 --- a/benchmark/bm_io_file_create.rb +++ b/benchmark/io_file_create.rb diff --git a/benchmark/bm_io_file_read.rb b/benchmark/io_file_read.rb index b9e796ed30..b9e796ed30 100644 --- a/benchmark/bm_io_file_read.rb +++ b/benchmark/io_file_read.rb diff --git a/benchmark/bm_io_file_write.rb b/benchmark/io_file_write.rb index aa1be0e5fe..aa1be0e5fe 100644 --- a/benchmark/bm_io_file_write.rb +++ b/benchmark/io_file_write.rb diff --git a/benchmark/io_nonblock_noex.rb b/benchmark/io_nonblock_noex.rb new file mode 100644 index 0000000000..da9357fdc6 --- /dev/null +++ b/benchmark/io_nonblock_noex.rb @@ -0,0 +1,22 @@ +nr = 1_000_000 +i = 0 +msg = '.' +buf = '.' +noex = { exception: false } +begin + r, w = IO.pipe + while i < nr + i += 1 + w.write_nonblock(msg, noex) + r.read_nonblock(1, buf, noex) + end +rescue ArgumentError # old Rubies + while i < nr + i += 1 + w.write_nonblock(msg) + r.read_nonblock(1, buf) + end +ensure + r.close + w.close +end diff --git a/benchmark/io_nonblock_noex2.rb b/benchmark/io_nonblock_noex2.rb new file mode 100644 index 0000000000..56819d049b --- /dev/null +++ b/benchmark/io_nonblock_noex2.rb @@ -0,0 +1,21 @@ +nr = 1_000_000 +i = 0 +msg = '.' +buf = '.' +begin + r, w = IO.pipe + while i < nr + i += 1 + w.write_nonblock(msg, exception: false) + r.read_nonblock(1, buf, exception: false) + end +rescue ArgumentError # old Rubies + while i < nr + i += 1 + w.write_nonblock(msg) + r.read_nonblock(1, buf) + end +ensure + r.close + w.close +end diff --git a/benchmark/io_pipe_rw.rb b/benchmark/io_pipe_rw.rb new file mode 100644 index 0000000000..6862a8ae61 --- /dev/null +++ b/benchmark/io_pipe_rw.rb @@ -0,0 +1,13 @@ +# Measure uncontended GVL performance via read/write with 1:1 threading +# If we switch to M:N threading, this will benchmark something else... +r, w = IO.pipe +src = '0'.freeze +dst = String.new +i = 0 +while i < 1_000_000 + i += 1 + w.write(src) + r.read(1, dst) +end +w.close +r.close diff --git a/benchmark/bm_io_select.rb b/benchmark/io_select.rb index 19248daeb1..19248daeb1 100644 --- a/benchmark/bm_io_select.rb +++ b/benchmark/io_select.rb diff --git a/benchmark/bm_io_select2.rb b/benchmark/io_select2.rb index 10e37d71b2..10e37d71b2 100644 --- a/benchmark/bm_io_select2.rb +++ b/benchmark/io_select2.rb diff --git a/benchmark/bm_io_select3.rb b/benchmark/io_select3.rb index 7d0ba1f092..7d0ba1f092 100644 --- a/benchmark/bm_io_select3.rb +++ b/benchmark/io_select3.rb diff --git a/benchmark/io_write.rb b/benchmark/io_write.rb new file mode 100644 index 0000000000..cdb409948b --- /dev/null +++ b/benchmark/io_write.rb @@ -0,0 +1,22 @@ +#!/usr/bin/env ruby + +require 'benchmark' + +i, o = IO.pipe +o.sync = true + +DOT = ".".freeze + +chunks = 100_000.times.collect{DOT} + +thread = Thread.new do + while i.read(1024) + end +end + +100.times do + o.write(*chunks) +end + +o.close +thread.join diff --git a/benchmark/irb_color.yml b/benchmark/irb_color.yml new file mode 100644 index 0000000000..ebdc8d7e8b --- /dev/null +++ b/benchmark/irb_color.yml @@ -0,0 +1,13 @@ +prelude: | + require 'irb/color' + code = <<~'CODE' + def self.foo # bar + :"erb #{ERB.new("<%= self %>", trim_mode: ?-).result}" + end + CODE +benchmark: + irb_color_complete: | + IRB::Color.colorize_code(code, complete: true) + irb_color_incomplete: | + IRB::Color.colorize_code(code, complete: false) +loop_count: 2000000 diff --git a/benchmark/irb_exec.yml b/benchmark/irb_exec.yml new file mode 100644 index 0000000000..28933f8b38 --- /dev/null +++ b/benchmark/irb_exec.yml @@ -0,0 +1,10 @@ +prelude: | + # frozen_string_literal: true + require 'rbconfig' + irb_f = [File.join(File.dirname(RbConfig.ruby), 'irb'), '-f'] +benchmark: + irb_exec: | + IO.popen(irb_f, 'w') do |io| + io.write('exit') + end +loop_count: 30 diff --git a/benchmark/iseq_load_from_binary.yml b/benchmark/iseq_load_from_binary.yml new file mode 100644 index 0000000000..7e9d73bdd4 --- /dev/null +++ b/benchmark/iseq_load_from_binary.yml @@ -0,0 +1,25 @@ +prelude: | + symbol = RubyVM::InstructionSequence.compile(":foo; :bar; :baz; :egg; :spam").to_binary + + define_method = RubyVM::InstructionSequence.compile(%{ + def foo; end + def bar; end + def baz; end + def egg; end + def spam; end + }).to_binary + + all = RubyVM::InstructionSequence.compile(%{ + module Foo; def foo; :foo; end; end + module Bar; def bar; :bar; end; end + module Baz; def baz; :baz; end; end + class Egg; def egg; :egg; end; end + class Spaml; def spam; :spam; end; end + }).to_binary + +benchmark: + symbol: RubyVM::InstructionSequence.load_from_binary(symbol) + define_method: RubyVM::InstructionSequence.load_from_binary(define_method) + all: RubyVM::InstructionSequence.load_from_binary(all) + +loop_count: 100_000 diff --git a/benchmark/ivar_extend.yml b/benchmark/ivar_extend.yml new file mode 100644 index 0000000000..eb9ee923f5 --- /dev/null +++ b/benchmark/ivar_extend.yml @@ -0,0 +1,23 @@ +prelude: | + class Embedded + def initialize + @a = 1 + @b = 1 + @c = 1 + end + end + + class Extended + def initialize + @a = 1 + @b = 1 + @c = 1 + @d = 1 + @e = 1 + @f = 1 + end + end +benchmark: + embedded: Embedded.new + extended: Extended.new +loop_count: 20_000_000 diff --git a/benchmark/kernel_clone.yml b/benchmark/kernel_clone.yml new file mode 100644 index 0000000000..069b23abcd --- /dev/null +++ b/benchmark/kernel_clone.yml @@ -0,0 +1,6 @@ +prelude: "object = Object.new" +benchmark: + clone: "object.clone" + clone_true: "object.clone(freeze: true)" + clone_false: "object.clone(freeze: false)" +loop_count: 10000 diff --git a/benchmark/kernel_float.yml b/benchmark/kernel_float.yml new file mode 100644 index 0000000000..215f6750fc --- /dev/null +++ b/benchmark/kernel_float.yml @@ -0,0 +1,5 @@ +benchmark: + float: "Float(42)" + float_true: "Float(42, exception: true)" + float_false: "Float(42, exception: false)" +loop_count: 10000 diff --git a/benchmark/kernel_tap.yml b/benchmark/kernel_tap.yml new file mode 100644 index 0000000000..4dcbb31b4d --- /dev/null +++ b/benchmark/kernel_tap.yml @@ -0,0 +1,6 @@ +prelude: | + obj = Object.new + x = nil +benchmark: + kernel_tap: obj.tap { |o| x = o } +loop_count: 20000000 diff --git a/benchmark/kernel_then.yml b/benchmark/kernel_then.yml new file mode 100644 index 0000000000..85f7341e33 --- /dev/null +++ b/benchmark/kernel_then.yml @@ -0,0 +1,6 @@ +benchmark: + kernel_then: 1.then { |i| i + 1 } + kernel_then_enum: 1.then + kernel_yield_self: 1.yield_self { |i| i + 1 } + kernel_yield_self_enum: 1.yield_self +loop_count: 20000000 diff --git a/benchmark/keyword_arguments.yml b/benchmark/keyword_arguments.yml new file mode 100644 index 0000000000..fce6bce0b8 --- /dev/null +++ b/benchmark/keyword_arguments.yml @@ -0,0 +1,13 @@ +prelude: | + h = {a: 1} + def kw(a: 1) a end + def kws(**kw) kw end +benchmark: + kw_to_kw: "kw(a: 1)" + kw_splat_to_kw: "kw(**h)" + kw_to_kw_splat: "kws(a: 1)" + kw_splat_to_kw_splat: "kws(**h)" + kw_and_splat_to_kw: "kw(a: 1, **h)" + kw_splats_to_kw: "kw(**h, **h)" + kw_and_splat_to_kw_splat: "kws(a: 1, **h)" + kw_splats_to_kw_splat: "kws(**h, **h)" diff --git a/benchmark/lib/benchmark_driver/output/driver.rb b/benchmark/lib/benchmark_driver/output/driver.rb new file mode 100644 index 0000000000..d22236e9fb --- /dev/null +++ b/benchmark/lib/benchmark_driver/output/driver.rb @@ -0,0 +1,36 @@ +require 'benchmark_driver/output/simple' + +# This replicates the legacy benchmark/driver.rb behavior. +class BenchmarkDriver::Output::Driver < BenchmarkDriver::Output::Simple + def initialize(*) + super + @stdout = $stdout + @strio = StringIO.new + $stdout = IOMultiplexer.new(@stdout, @strio) + end + + def with_benchmark(*) + super + ensure + logfile = "bmlog-#{Time.now.strftime('%Y%m%d-%H%M%S')}.#{$$}.log" + puts "\nLog file: #{logfile}" + + $stdout = @stdout + File.write(logfile, @strio.tap(&:rewind).read) + end + + class IOMultiplexer + def initialize(io1, io2) + @io1 = io1 + @io2 = io2 + end + + [:write, :sync, :sync=, :puts, :print, :flush].each do |method| + define_method(method) do |*args| + @io1.send(method, *args) + @io2.send(method, *args) + end + end + end + private_constant :IOMultiplexer +end diff --git a/benchmark/lib/benchmark_driver/runner/cstime.rb b/benchmark/lib/benchmark_driver/runner/cstime.rb new file mode 100644 index 0000000000..3c3453e527 --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/cstime.rb @@ -0,0 +1,22 @@ +require 'benchmark_driver/runner/total' + +class BenchmarkDriver::Runner::Cstime < BenchmarkDriver::Runner::Total + METRIC = BenchmarkDriver::Metric.new(name: 'cstime', unit: 's', larger_better: false) + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) + + private + + # Overriding BenchmarkDriver::Runner::Total#metric + def metric + METRIC + end + + # Overriding BenchmarkDriver::Runner::Total#target + def target + :cstime + end +end diff --git a/benchmark/lib/benchmark_driver/runner/cutime.rb b/benchmark/lib/benchmark_driver/runner/cutime.rb new file mode 100644 index 0000000000..e139962ef2 --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/cutime.rb @@ -0,0 +1,22 @@ +require 'benchmark_driver/runner/total' + +class BenchmarkDriver::Runner::Cutime < BenchmarkDriver::Runner::Total + METRIC = BenchmarkDriver::Metric.new(name: 'cutime', unit: 's', larger_better: false) + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) + + private + + # Overriding BenchmarkDriver::Runner::Total#metric + def metric + METRIC + end + + # Overriding BenchmarkDriver::Runner::Total#target + def target + :cutime + end +end diff --git a/benchmark/lib/benchmark_driver/runner/peak.rb b/benchmark/lib/benchmark_driver/runner/peak.rb new file mode 100644 index 0000000000..d04f2e51ff --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/peak.rb @@ -0,0 +1,151 @@ +require 'benchmark_driver/struct' +require 'benchmark_driver/metric' +require 'benchmark_driver/default_job' +require 'benchmark_driver/default_job_parser' +require 'tempfile' + +class BenchmarkDriver::Runner::Peak + METRIC = BenchmarkDriver::Metric.new( + name: 'Peak memory usage', unit: 'bytes', larger_better: false, worse_word: 'larger', + ) + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) + + # @param [BenchmarkDriver::Config::RunnerConfig] config + # @param [BenchmarkDriver::Output] output + # @param [BenchmarkDriver::Context] contexts + def initialize(config:, output:, contexts:) + @config = config + @output = output + @contexts = contexts + end + + # This method is dynamically called by `BenchmarkDriver::JobRunner.run` + # @param [Array<BenchmarkDriver::Runner::Peak::Job>] jobs + def run(jobs) + if jobs.any? { |job| job.loop_count.nil? } + jobs = jobs.map do |job| + job.loop_count ? job : Job.new(job.to_h.merge(loop_count: 1)) + end + end + + @output.with_benchmark do + jobs.each do |job| + @output.with_job(name: job.name) do + job.runnable_contexts(@contexts).each do |context| + value = BenchmarkDriver::Repeater.with_repeat(config: @config, larger_better: false) do + run_benchmark(job, context: context) + end + @output.with_context(name: context.name, executable: context.executable, gems: context.gems, prelude: context.prelude) do + @output.report(values: { metric => value }, loop_count: job.loop_count) + end + end + end + end + end + end + + private + + # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil + # @param [BenchmarkDriver::Context] context + # @return [BenchmarkDriver::Metrics] + def run_benchmark(job, context:) + benchmark = BenchmarkScript.new( + preludes: [context.prelude, job.prelude], + script: job.script, + teardown: job.teardown, + loop_count: job.loop_count, + ) + + memory_status = File.expand_path('../../../../tool/lib/memory_status', __dir__) + Tempfile.open(['benchmark_driver-', '.rb']) do |f| + with_script(benchmark.render) do |path| + output = IO.popen([*context.executable.command, path, f.path, target, memory_status], &:read) + if $?.success? + Integer(f.read) + else + $stdout.print(output) + BenchmarkDriver::Result::ERROR + end + end + end + end + + # Overridden by BenchmarkDriver::Runner::Size + def target + 'peak' + end + + # Overridden by BenchmarkDriver::Runner::Size + def metric + METRIC + end + + def with_script(script) + if @config.verbose >= 2 + sep = '-' * 30 + $stdout.puts "\n\n#{sep}[Script begin]#{sep}\n#{script}#{sep}[Script end]#{sep}\n\n" + end + + Tempfile.open(['benchmark_driver-', '.rb']) do |f| + f.puts script + f.close + return yield(f.path) + end + end + + # @param [String] prelude + # @param [String] script + # @param [String] teardown + # @param [Integer] loop_count + BenchmarkScript = ::BenchmarkDriver::Struct.new(:preludes, :script, :teardown, :loop_count) do + def render + prelude = preludes.reject(&:nil?).reject(&:empty?).join("\n") + <<-RUBY +#{prelude} +#{while_loop(script, loop_count)} +#{teardown} + +result_file, target, memory_status = ARGV +require_relative memory_status + +ms = Memory::Status.new +case target.to_sym +when :peak + key = ms.respond_to?(:hwm) ? :hwm : :peak +when :size + key = ms.respond_to?(:rss) ? :rss : :size +else + raise('unexpected target: ' + target) +end + +File.write(result_file, ms[key]) + RUBY + end + + private + + def while_loop(content, times) + if !times.is_a?(Integer) || times <= 0 + raise ArgumentError.new("Unexpected times: #{times.inspect}") + end + + if times > 1 + <<-RUBY +__bmdv_i = 0 +while __bmdv_i < #{times} + #{content} + __bmdv_i += 1 +end + RUBY + else + content + end + end + end + private_constant :BenchmarkScript +end diff --git a/benchmark/lib/benchmark_driver/runner/ractor.rb b/benchmark/lib/benchmark_driver/runner/ractor.rb new file mode 100644 index 0000000000..fd9c2dd4db --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/ractor.rb @@ -0,0 +1,122 @@ +require 'erb' + +# A runner to measure performance *inside* Ractor +class BenchmarkDriver::Runner::Ractor < BenchmarkDriver::Runner::Ips + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) do + attr_accessor :ractor + end + + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]).extend(Module.new{ + def parse(ractor: 1, **kwargs) + super(**kwargs).each do |job| + job.ractor = ractor + end + end + }) + + private + + unless private_instance_methods.include?(:run_benchmark) + raise "#run_benchmark is no longer defined in BenchmarkDriver::Runner::Ips" + end + + # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil + # @param [BenchmarkDriver::Context] context + # @return [BenchmarkDriver::Metrics] + def run_benchmark(job, context:) + benchmark = BenchmarkScript.new( + preludes: [context.prelude, job.prelude], + script: job.script, + teardown: job.teardown, + loop_count: job.loop_count, + ) + + results = job.ractor.times.map do + Tempfile.open('benchmark_driver_result') + end + duration = with_script(benchmark.render(results: results.map(&:path))) do |path| + success = execute(*context.executable.command, path, exception: false) + if success && ((value = results.map { |f| Float(f.read) }.max) > 0) + value + else + BenchmarkDriver::Result::ERROR + end + end + results.each(&:close) + + value_duration( + loop_count: job.loop_count, + duration: duration, + ) + end + + # @param [String] prelude + # @param [String] script + # @param [String] teardown + # @param [Integer] loop_count + BenchmarkScript = ::BenchmarkDriver::Struct.new(:preludes, :script, :teardown, :loop_count) do + # @param [String] result - A file to write result + def render(results:) + prelude = preludes.reject(&:nil?).reject(&:empty?).join("\n") + ERB.new(<<-RUBY).result_with_hash(results: results) +Warning[:experimental] = false +# shareable-constant-value: experimental_everything +#{prelude} + +if #{loop_count} == 1 + __bmdv_loop_before = 0 + __bmdv_loop_after = 0 +else + __bmdv_loop_before = Time.new + #{while_loop('', loop_count, id: 0)} + __bmdv_loop_after = Time.new +end + +__bmdv_ractors = [] +<% results.size.times do %> +__bmdv_ractors << Ractor.new(__bmdv_loop_after - __bmdv_loop_before) { |__bmdv_loop_time| + __bmdv_time = Time + __bmdv_script_before = __bmdv_time.new + #{while_loop(script, loop_count, id: 1)} + __bmdv_script_after = __bmdv_time.new + + (__bmdv_script_after - __bmdv_script_before) - __bmdv_loop_time +} +<% end %> + +# Wait for all Ractors before executing code to write results +__bmdv_ractors.map!(&:value) + +<% results.each do |result| %> +File.write(<%= result.dump %>, __bmdv_ractors.shift) +<% end %> + +#{teardown} + RUBY + end + + private + + # id is to prevent: + # can not isolate a Proc because it accesses outer variables (__bmdv_i) + def while_loop(content, times, id:) + if !times.is_a?(Integer) || times <= 0 + raise ArgumentError.new("Unexpected times: #{times.inspect}") + elsif times == 1 + return content + end + + # TODO: execute in batch + <<-RUBY +__bmdv_i#{id} = 0 +while __bmdv_i#{id} < #{times} + #{content} + __bmdv_i#{id} += 1 +end + RUBY + end + end + private_constant :BenchmarkScript +end diff --git a/benchmark/lib/benchmark_driver/runner/size.rb b/benchmark/lib/benchmark_driver/runner/size.rb new file mode 100644 index 0000000000..1b31f901c7 --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/size.rb @@ -0,0 +1,25 @@ +require 'benchmark_driver/runner/peak' + +# Actually the same as BenchmarkDriver::Runner::Memory +class BenchmarkDriver::Runner::Size < BenchmarkDriver::Runner::Peak + METRIC = BenchmarkDriver::Metric.new( + name: 'Max resident set size', unit: 'bytes', larger_better: false, worse_word: 'larger', + ) + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) + + private + + # Overriding BenchmarkDriver::Runner::Peak#metric + def metric + METRIC + end + + # Overriding BenchmarkDriver::Runner::Peak#target + def target + 'size' + end +end diff --git a/benchmark/lib/benchmark_driver/runner/stime.rb b/benchmark/lib/benchmark_driver/runner/stime.rb new file mode 100644 index 0000000000..4577fb0bf8 --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/stime.rb @@ -0,0 +1,22 @@ +require 'benchmark_driver/runner/total' + +class BenchmarkDriver::Runner::Stime < BenchmarkDriver::Runner::Total + METRIC = BenchmarkDriver::Metric.new(name: 'stime', unit: 's', larger_better: false) + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) + + private + + # Overriding BenchmarkDriver::Runner::Total#metric + def metric + METRIC + end + + # Overriding BenchmarkDriver::Runner::Total#target + def target + :stime + end +end diff --git a/benchmark/lib/benchmark_driver/runner/total.rb b/benchmark/lib/benchmark_driver/runner/total.rb new file mode 100644 index 0000000000..64dc14f84e --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/total.rb @@ -0,0 +1,137 @@ +require 'benchmark_driver/struct' +require 'benchmark_driver/metric' +require 'benchmark_driver/default_job' +require 'benchmark_driver/default_job_parser' +require 'tempfile' + +class BenchmarkDriver::Runner::Total + METRIC = BenchmarkDriver::Metric.new(name: 'Total time', unit: 's', larger_better: false) + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) + + # @param [BenchmarkDriver::Config::RunnerConfig] config + # @param [BenchmarkDriver::Output] output + # @param [BenchmarkDriver::Context] contexts + def initialize(config:, output:, contexts:) + @config = config + @output = output + @contexts = contexts + end + + # This method is dynamically called by `BenchmarkDriver::JobRunner.run` + # @param [Array<BenchmarkDriver::Runner::Total::Job>] jobs + def run(jobs) + if jobs.any? { |job| job.loop_count.nil? } + raise 'missing loop_count is not supported in Ruby repository' + end + + @output.with_benchmark do + jobs.each do |job| + @output.with_job(name: job.name) do + job.runnable_contexts(@contexts).each do |context| + duration = BenchmarkDriver::Repeater.with_repeat(config: @config, larger_better: false) do + run_benchmark(job, context: context) + end + @output.with_context(name: context.name, executable: context.executable, gems: context.gems, prelude: context.prelude) do + @output.report(values: { metric => duration }, duration: duration, loop_count: job.loop_count) + end + end + end + end + end + end + + private + + # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil + # @param [BenchmarkDriver::Context] context + # @return [BenchmarkDriver::Metrics] + def run_benchmark(job, context:) + benchmark = BenchmarkScript.new( + preludes: [context.prelude, job.prelude], + script: job.script, + teardown: job.teardown, + loop_count: job.loop_count, + ) + + Tempfile.open(['benchmark_driver-', '.rb']) do |f| + with_script(benchmark.render(result: f.path, target: target)) do |path| + IO.popen([*context.executable.command, path], &:read) # TODO: print stdout if verbose=2 + if $?.success? + Float(f.read) + else + BenchmarkDriver::Result::ERROR + end + end + end + end + + # This method is overridden by some subclasses + def metric + METRIC + end + + # This method is overridden by some subclasses + def target + :total + end + + def with_script(script) + if @config.verbose >= 2 + sep = '-' * 30 + $stdout.puts "\n\n#{sep}[Script begin]#{sep}\n#{script}#{sep}[Script end]#{sep}\n\n" + end + + Tempfile.open(['benchmark_driver-', '.rb']) do |f| + f.puts script + f.close + return yield(f.path) + end + end + + # @param [String] prelude + # @param [String] script + # @param [String] teardown + # @param [Integer] loop_count + BenchmarkScript = ::BenchmarkDriver::Struct.new(:preludes, :script, :teardown, :loop_count) do + # @param [String] result - A file to write result + def render(result:, target:) + prelude = preludes.reject(&:nil?).reject(&:empty?).join("\n") + <<-RUBY +#{prelude} + +require 'benchmark' +__bmdv_result = Benchmark.measure { + #{while_loop(script, loop_count)} +} + +#{teardown} + +File.write(#{result.dump}, __bmdv_result.#{target}) + RUBY + end + + private + + def while_loop(content, times) + if !times.is_a?(Integer) || times <= 0 + raise ArgumentError.new("Unexpected times: #{times.inspect}") + elsif times == 1 + return content + end + + # TODO: execute in batch + <<-RUBY +__bmdv_i = 0 +while __bmdv_i < #{times} + #{content} + __bmdv_i += 1 +end + RUBY + end + end + private_constant :BenchmarkScript +end diff --git a/benchmark/lib/benchmark_driver/runner/utime.rb b/benchmark/lib/benchmark_driver/runner/utime.rb new file mode 100644 index 0000000000..b61d83a188 --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/utime.rb @@ -0,0 +1,22 @@ +require 'benchmark_driver/runner/total' + +class BenchmarkDriver::Runner::Utime < BenchmarkDriver::Runner::Total + METRIC = BenchmarkDriver::Metric.new(name: 'utime', unit: 's', larger_better: false) + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]) + + private + + # Overriding BenchmarkDriver::Runner::Total#metric + def metric + METRIC + end + + # Overriding BenchmarkDriver::Runner::Total#target + def target + :utime + end +end diff --git a/benchmark/lib/load.rb b/benchmark/lib/load.rb new file mode 100644 index 0000000000..31b770c484 --- /dev/null +++ b/benchmark/lib/load.rb @@ -0,0 +1,18 @@ +# How to use this file: +# 1. write a `$(srcdir)/test.rb` like: +=begin +require_relative 'benchmark/lib/load' + +Benchmark.driver(repeat_count: 5){|x| + x.executable name: 'clean-miniruby', command: %w'../clean-trunk/miniruby' + x.executable name: 'modif-miniruby', command: %w'./miniruby' + + x.report %q{ + h = {a: 1, b: 2, c: 3, d: 4} + } +} +=end +# +# 2. `make run` +$:.unshift(File.join(__dir__, '../benchmark-driver/lib')) +require 'benchmark_driver' diff --git a/benchmark/loop_each.yml b/benchmark/loop_each.yml new file mode 100644 index 0000000000..1c757185a8 --- /dev/null +++ b/benchmark/loop_each.yml @@ -0,0 +1,4 @@ +prelude: | + arr = [nil] * 30_000_000 +benchmark: + loop_each: arr.each{|e|} diff --git a/benchmark/bm_loop_for.rb b/benchmark/loop_for.rb index 0fc4cc1511..0fc4cc1511 100644 --- a/benchmark/bm_loop_for.rb +++ b/benchmark/loop_for.rb diff --git a/benchmark/bm_loop_generator.rb b/benchmark/loop_generator.rb index d3375c744c..6a3194b670 100644 --- a/benchmark/bm_loop_generator.rb +++ b/benchmark/loop_generator.rb @@ -1,4 +1,4 @@ -max = 600000 +max = 6000000 if defined? Fiber gen = (1..max).each diff --git a/benchmark/bm_loop_times.rb b/benchmark/loop_times.rb index 521f72ad1a..521f72ad1a 100644 --- a/benchmark/bm_loop_times.rb +++ b/benchmark/loop_times.rb diff --git a/benchmark/loop_times_megamorphic.yml b/benchmark/loop_times_megamorphic.yml new file mode 100644 index 0000000000..f9343ba897 --- /dev/null +++ b/benchmark/loop_times_megamorphic.yml @@ -0,0 +1,7 @@ +prelude: | + eval(<<~EOS) + def loop_times_megamorphic + #{"1.times {|i|};" * 1000} + end + EOS +benchmark: loop_times_megamorphic diff --git a/benchmark/bm_loop_whileloop.rb b/benchmark/loop_whileloop.rb index 0072822c06..0072822c06 100644 --- a/benchmark/bm_loop_whileloop.rb +++ b/benchmark/loop_whileloop.rb diff --git a/benchmark/bm_loop_whileloop2.rb b/benchmark/loop_whileloop2.rb index 47d02dffc4..47d02dffc4 100644 --- a/benchmark/bm_loop_whileloop2.rb +++ b/benchmark/loop_whileloop2.rb diff --git a/benchmark/make_fasta_output.rb b/benchmark/make_fasta_output.rb deleted file mode 100644 index b6d787ae27..0000000000 --- a/benchmark/make_fasta_output.rb +++ /dev/null @@ -1,19 +0,0 @@ -# prepare 'fasta.output' - -def prepare_fasta_output n - filebase = File.join(File.dirname($0), 'fasta.output') - script = File.join(File.dirname($0), 'bm_so_fasta.rb') - file = "#{filebase}.#{n}" - - unless FileTest.exist?(file) - STDERR.puts "preparing #{file}" - - open(file, 'w'){|f| - ARGV[0] = n - $stdout = f - load script - $stdout = STDOUT - } - end -end - diff --git a/benchmark/marshal_dump_flo.rb b/benchmark/marshal_dump_flo.rb new file mode 100644 index 0000000000..9b8d0c6afb --- /dev/null +++ b/benchmark/marshal_dump_flo.rb @@ -0,0 +1,2 @@ +bug10761 = 10000.times.map { |x| x.to_f } +100.times { Marshal.dump(bug10761) } diff --git a/benchmark/marshal_dump_load_geniv.rb b/benchmark/marshal_dump_load_geniv.rb new file mode 100644 index 0000000000..8252ad90fa --- /dev/null +++ b/benchmark/marshal_dump_load_geniv.rb @@ -0,0 +1,10 @@ +a = '' +a.instance_eval do + @a = :a + @b = :b + @c = :c +end +100000.times do + a = Marshal.load(Marshal.dump(a)) +end +#p(a.instance_eval { @a == :a && @b == :b && @c == :c }) diff --git a/benchmark/marshal_dump_load_integer.yml b/benchmark/marshal_dump_load_integer.yml new file mode 100644 index 0000000000..78ebf823d2 --- /dev/null +++ b/benchmark/marshal_dump_load_integer.yml @@ -0,0 +1,22 @@ +prelude: | + smallint_array = 1000.times.map { |x| x } + bigint32_array = 1000.times.map { |x| x + 2**32 } + bigint64_array = 1000.times.map { |x| x + 2**64 } + + smallint_dump = Marshal.dump(smallint_array) + bigint32_dump = Marshal.dump(bigint32_array) + bigint64_dump = Marshal.dump(bigint64_array) +benchmark: + marshal_dump_integer_small: | + Marshal.dump(smallint_array) + marshal_dump_integer_over_32_bit: | + Marshal.dump(bigint32_array) + marshal_dump_integer_over_64_bit: | + Marshal.dump(bigint64_array) + marshal_load_integer_small: | + Marshal.load(smallint_dump) + marshal_load_integer_over_32_bit: | + Marshal.load(bigint32_dump) + marshal_load_integer_over_64_bit: | + Marshal.load(bigint64_dump) +loop_count: 4000 diff --git a/benchmark/marshal_dump_load_time.rb b/benchmark/marshal_dump_load_time.rb new file mode 100644 index 0000000000..e29743b791 --- /dev/null +++ b/benchmark/marshal_dump_load_time.rb @@ -0,0 +1 @@ +100000.times { Marshal.load(Marshal.dump(Time.now)) } diff --git a/benchmark/masgn.yml b/benchmark/masgn.yml new file mode 100644 index 0000000000..31cb8ee4a3 --- /dev/null +++ b/benchmark/masgn.yml @@ -0,0 +1,53 @@ +prelude: | + a = [nil] * 3 + b = Class.new{attr_writer :a, :b, :c}.new + c = d = e = f = g = h = i = nil +benchmark: + array2_2: "c = (a[0], a[1] = 1, 2)" + array2_3: "c = (a[0], a[1] = 1, 2, 3)" + array3_2: "c = (a[0], a[1], a[2] = 1, 2)" + array3_3: "c = (a[0], a[1], a[2] = 1, 2, 3)" + attr2_2: "c = (b.a, b.b = 1, 2)" + attr2_3: "c = (b.a, b.b = 1, 2, 3)" + attr3_2: "c = (b.a, b.b, b.c = 1, 2)" + attr3_3: "c = (b.a, b.b, b.c = 1, 2, 3)" + lvar2_2: "c = (d, e = 1, 2)" + lvar2_3: "c = (d, e = 1, 2, 3)" + lvar3_2: "c = (d, e, f = 1, 2)" + lvar3_3: "c = (d, e, f = 1, 2, 3)" + array2_2p: "(a[0], a[1] = 1, 2; nil)" + array2_3p: "(a[0], a[1] = 1, 2, 3; nil)" + array3_2p: "(a[0], a[1], a[2] = 1, 2; nil)" + array3_3p: "(a[0], a[1], a[2] = 1, 2, 3; nil)" + attr2_2p: "(b.a, b.b = 1, 2; nil)" + attr2_3p: "(b.a, b.b = 1, 2, 3; nil)" + attr3_2p: "(b.a, b.b, b.c = 1, 2; nil)" + attr3_3p: "(b.a, b.b, b.c = 1, 2, 3; nil)" + lvar2_2p: "(d, e = 1, 2; nil)" + lvar2_3p: "(d, e = 1, 2, 3; nil)" + lvar3_2p: "(d, e, f = 1, 2; nil)" + lvar3_3p: "(d, e, f = 1, 2, 3; nil)" + array2_2lv: "c = (a[0], a[1] = g, h)" + array2_ilv: "c = (a[0], a[1] = g, h, i)" + arrayi_2lv: "c = (a[0], a[1], a[2] = g, h)" + arrayi_ilv: "c = (a[0], a[1], a[2] = g, h, i)" + attr2_2lv: "c = (b.a, b.b = g, h)" + attr2_ilv: "c = (b.a, b.b = g, h, i)" + attri_2lv: "c = (b.a, b.b, b.c = g, h)" + attri_ilv: "c = (b.a, b.b, b.c = g, h, i)" + lvar2_2lv: "c = (d, e = g, h)" + lvar2_ilv: "c = (d, e = g, h, i)" + lvari_2lv: "c = (d, e, f = g, h)" + lvari_ilv: "c = (d, e, f = g, h, i)" + array2_2plv: "(a[0], a[1] = g, h; nil)" + array2_iplv: "(a[0], a[1] = g, h, i; nil)" + arrayi_2plv: "(a[0], a[1], a[2] = g, h; nil)" + arrayi_iplv: "(a[0], a[1], a[2] = g, h, i; nil)" + attr2_2plv: "(b.a, b.b = g, h; nil)" + attr2_iplv: "(b.a, b.b = g, h, i; nil)" + attri_2plv: "(b.a, b.b, b.c = g, h; nil)" + attri_iplv: "(b.a, b.b, b.c = g, h, i; nil)" + lvar2_2plv: "(d, e = g, h; nil)" + lvar2_iplv: "(d, e = g, h, i; nil)" + lvari_2plv: "(d, e, f = g, h; nil)" + lvari_iplv: "(d, e, f = g, h, i; nil)" diff --git a/benchmark/match_gt4.rb b/benchmark/match_gt4.rb new file mode 100644 index 0000000000..ffda109912 --- /dev/null +++ b/benchmark/match_gt4.rb @@ -0,0 +1 @@ +1000000.times { /(.)(.)(\d+)(\d)/.match("THX1138.") } diff --git a/benchmark/match_small.rb b/benchmark/match_small.rb new file mode 100644 index 0000000000..3b743d484a --- /dev/null +++ b/benchmark/match_small.rb @@ -0,0 +1 @@ +1000000.times { 'haystack'.match(/hay/) } diff --git a/benchmark/method_bind_call.yml b/benchmark/method_bind_call.yml new file mode 100644 index 0000000000..9e0e046ed4 --- /dev/null +++ b/benchmark/method_bind_call.yml @@ -0,0 +1,16 @@ +prelude: | + named_module = Kernel + + module FakeName + def self.name + "NotMyame".freeze + end + end + + MOD_NAME = Module.instance_method(:name) + +benchmark: + fastpath: MOD_NAME.bind_call(Kernel) + slowpath: MOD_NAME.bind_call(FakeName) + +loop_count: 100_000 diff --git a/benchmark/module_eqq.yml b/benchmark/module_eqq.yml new file mode 100644 index 0000000000..2f9c490d92 --- /dev/null +++ b/benchmark/module_eqq.yml @@ -0,0 +1,32 @@ +prelude: | + module SomeModule; end + class SimpleClass; end + class MediumClass + 10.times { include Module.new } + end + class LargeClass + 100.times { include Module.new } + end + class HugeClass + 300.times { include Module.new } + end + SimpleObj = SimpleClass.new + MediumObj = MediumClass.new + LargeObj = LargeClass.new + HugeObj = HugeClass.new +benchmark: + simple_class_eqq_simple_obj: | + SimpleClass === SimpleObj + medium_class_eqq_simple_obj: | + MediumClass === SimpleObj + simple_class_eqq_medium_obj: | + SimpleClass === MediumObj + simple_class_eqq_large_obj: | + SimpleClass === LargeObj + simple_class_eqq_huge_obj: | + SimpleClass === HugeObj + simple_class_eqq_module: | + SimpleClass === HugeObj + module_eqq_module: | + SomeModule === HugeObj +loop_count: 10000000 diff --git a/benchmark/nil_p.yml b/benchmark/nil_p.yml new file mode 100644 index 0000000000..79ba4f2177 --- /dev/null +++ b/benchmark/nil_p.yml @@ -0,0 +1,9 @@ +prelude: | + class Niller; def nil?; true; end; end + xnil, notnil = nil, Object.new + niller = Niller.new +benchmark: + - xnil.nil? + - notnil.nil? + - niller.nil? +loop_count: 10000000 diff --git a/benchmark/nilclass.yml b/benchmark/nilclass.yml new file mode 100644 index 0000000000..66234c4cdf --- /dev/null +++ b/benchmark/nilclass.yml @@ -0,0 +1,16 @@ +prelude: | + def a = nil +benchmark: + rationalize: + nil.rationalize + to_c: | + nil.to_c + to_i: | + nil.to_i + to_f: | + nil.to_f + to_r: | + nil.to_r + splat: | + a(*nil) +loop_count: 100000 diff --git a/benchmark/num_zero_p.yml b/benchmark/num_zero_p.yml new file mode 100644 index 0000000000..2195963433 --- /dev/null +++ b/benchmark/num_zero_p.yml @@ -0,0 +1,8 @@ +benchmark: + - 0.zero? + - 1.zero? + - 0r.zero? + - 1r.zero? + - 0i.zero? + - 1i.zero? +loop_count: 50000000 diff --git a/benchmark/numeric_methods.yml b/benchmark/numeric_methods.yml new file mode 100644 index 0000000000..1384902935 --- /dev/null +++ b/benchmark/numeric_methods.yml @@ -0,0 +1,29 @@ +prelude: | + int = 42 + flo = 4.2 +benchmark: + real?: | + int.real? + integer?: | + flo.integer? + finite?: | + int.finite? + infinite?: | + int.infinite? + integer_real: | + int.real + float_real: | + flo.real + integr_imag: | + int.imag + float_imag: | + flo.imag + integer_conj: | + int.conj + float_conj: | + flo.conj + integer_numerator: | + int.numerator + integer_denominator: | + int.denominator +loop_count: 20000000 diff --git a/benchmark/object_allocate.yml b/benchmark/object_allocate.yml new file mode 100644 index 0000000000..c6269923f0 --- /dev/null +++ b/benchmark/object_allocate.yml @@ -0,0 +1,49 @@ +prelude: | + class Eight + 8.times { include(Module.new) } + end + class ThirtyTwo + 32.times { include(Module.new) } + end + class SixtyFour + 64.times { include(Module.new) } + end + class OneTwentyEight + 128.times { include(Module.new) } + end + class OnePositional + def initialize a; end + end + class TwoPositional + def initialize a, b; end + end + class ThreePositional + def initialize a, b, c; end + end + class FourPositional + def initialize a, b, c, d; end + end + class KWArg + def initialize a:, b:, c:, d: + end + end + class Mixed + def initialize a, b, c:, d: + end + end + # Disable GC to see raw throughput: + GC.disable +benchmark: + allocate_8_deep: Eight.new + allocate_32_deep: ThirtyTwo.new + allocate_64_deep: SixtyFour.new + allocate_128_deep: OneTwentyEight.new + allocate_1_positional_params: OnePositional.new(1) + allocate_2_positional_params: TwoPositional.new(1, 2) + allocate_3_positional_params: ThreePositional.new(1, 2, 3) + allocate_4_positional_params: FourPositional.new(1, 2, 3, 4) + allocate_kwarg_params: "KWArg.new(a: 1, b: 2, c: 3, d: 4)" + allocate_mixed_params: "Mixed.new(1, 2, c: 3, d: 4)" + allocate_no_params: "Object.new" + allocate_allocate: "Object.allocate" +loop_count: 100000 diff --git a/benchmark/object_class.yml b/benchmark/object_class.yml new file mode 100644 index 0000000000..1e5409d1e2 --- /dev/null +++ b/benchmark/object_class.yml @@ -0,0 +1,40 @@ +prelude: | + def get_class(obj) + i = 10_000 + while i > 0 + i -= 1 + # 100 times per loop + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + end + end + + class Obj + end + obj = Obj.new + + singleton = Obj.new + def singleton.bar + end + + extended = Obj.new + 2.times do + extended.extend Module.new + end + + immediate = 1.4 +benchmark: + obj: get_class(obj) + extended: get_class(extended) + singleton: get_class(singleton) + immediate: get_class(immediate) +loop_count: 1000 diff --git a/benchmark/object_id.yml b/benchmark/object_id.yml new file mode 100644 index 0000000000..2bd52b923f --- /dev/null +++ b/benchmark/object_id.yml @@ -0,0 +1,4 @@ +benchmark: + baseline: "Object.new" + object_id: "Object.new.object_id" +# loop_count: 100000 diff --git a/benchmark/objspace_dump_all.yml b/benchmark/objspace_dump_all.yml new file mode 100644 index 0000000000..ebab562d2e --- /dev/null +++ b/benchmark/objspace_dump_all.yml @@ -0,0 +1,13 @@ +prelude: | + require 'objspace' + require 'tempfile' + $objs = 1_000.times.map { Object.new } + $strings = 1_000.times.map { |i| "string #{i}" } + $file = Tempfile.new('heap') + $dev_null = File.open(File::NULL, 'w+') + +benchmark: + dump_all_string: "ObjectSpace.dump_all(output: :string)" + dump_all_file: "ObjectSpace.dump_all(output: $file)" + dump_all_dev_null: "ObjectSpace.dump_all(output: $dev_null)" +loop_count: 1 diff --git a/benchmark/other-lang/fact.py b/benchmark/other-lang/fact.py index 01593965d9..1ce9f76275 100644 --- a/benchmark/other-lang/fact.py +++ b/benchmark/other-lang/fact.py @@ -3,7 +3,7 @@ def factL(n): r = 1 - for x in range(2, n): + for x in range(2, n+1): r *= x return r diff --git a/benchmark/pm_array.yml b/benchmark/pm_array.yml new file mode 100644 index 0000000000..babb65a289 --- /dev/null +++ b/benchmark/pm_array.yml @@ -0,0 +1,19 @@ +prelude: | + def call(*val) + case val + in [String => body] + [200, {}, [body]] + in [Integer => status] + [status, {}, [""]] + in [Integer, String] => response + [response[0], {}, [response[1]]] + in [Integer, Hash, String] => response + [response[0], response[1], [response[2]]] + end + end + +benchmark: + first_match: call("ok") + second_match: call(401) + third_match: call(200, "ok") + fourth_match: call(201, {}, "created") diff --git a/benchmark/prepare_so_count_words.rb b/benchmark/prepare_so_count_words.rb deleted file mode 100644 index ee2138cdb2..0000000000 --- a/benchmark/prepare_so_count_words.rb +++ /dev/null @@ -1,15 +0,0 @@ -# prepare 'wc.input' - -def prepare_wc_input - wcinput = File.join(File.dirname($0), 'wc.input') - wcbase = File.join(File.dirname($0), 'wc.input.base') - unless FileTest.exist?(wcinput) - data = File.read(wcbase) - 13.times{ - data << data - } - open(wcinput, 'w'){|f| f.write data} - end -end - -prepare_wc_input diff --git a/benchmark/prepare_so_k_nucleotide.rb b/benchmark/prepare_so_k_nucleotide.rb deleted file mode 100644 index d83aeb7a7e..0000000000 --- a/benchmark/prepare_so_k_nucleotide.rb +++ /dev/null @@ -1,2 +0,0 @@ -require_relative 'make_fasta_output' -prepare_fasta_output(100_000) diff --git a/benchmark/prepare_so_reverse_complement.rb b/benchmark/prepare_so_reverse_complement.rb deleted file mode 100644 index da3ec2df14..0000000000 --- a/benchmark/prepare_so_reverse_complement.rb +++ /dev/null @@ -1,2 +0,0 @@ -require_relative 'make_fasta_output' -prepare_fasta_output(2_500_000) diff --git a/benchmark/ractor_const.yml b/benchmark/ractor_const.yml new file mode 100644 index 0000000000..d7ab74bdca --- /dev/null +++ b/benchmark/ractor_const.yml @@ -0,0 +1,4 @@ +type: lib/benchmark_driver/runner/ractor +benchmark: + ractor_const: Object +ractor: 1 diff --git a/benchmark/ractor_float_to_s.yml b/benchmark/ractor_float_to_s.yml new file mode 100644 index 0000000000..8f492be668 --- /dev/null +++ b/benchmark/ractor_float_to_s.yml @@ -0,0 +1,8 @@ +type: lib/benchmark_driver/runner/ractor +prelude: | + FLOATS = [*0.0.step(1.0, 0.001)] +benchmark: + ractor_float_to_s: | + FLOATS.each {|f| f.to_s} +loop_count: 100 +ractor: 2 diff --git a/benchmark/ractor_string_fstring.yml b/benchmark/ractor_string_fstring.yml new file mode 100644 index 0000000000..14b92d8fd8 --- /dev/null +++ b/benchmark/ractor_string_fstring.yml @@ -0,0 +1,18 @@ +type: lib/benchmark_driver/runner/ractor +benchmark: + ractor_fstring_random: | + i = 0 + str = "same".dup + while i < 2000000 + -(i.to_s.freeze) + i += 1 + end + ractor_fstring_same: | + i = 0 + str = "same".dup + while i < 2000000 + -str + i += 1 + end +loop_count: 1 +ractor: 4 diff --git a/benchmark/range_bsearch_bignum.yml b/benchmark/range_bsearch_bignum.yml new file mode 100644 index 0000000000..5730c93fcf --- /dev/null +++ b/benchmark/range_bsearch_bignum.yml @@ -0,0 +1,10 @@ +prelude: | + first = 2**100 + last = 2**1000 + mid = (first + last) / 2 + r = first..last + +benchmark: + first: r.bsearch { |x| x >= first } + mid: r.bsearch { |x| x >= mid } + last: r.bsearch { |x| x >= last } diff --git a/benchmark/range_bsearch_endpointless.yml b/benchmark/range_bsearch_endpointless.yml new file mode 100644 index 0000000000..8d7bedb662 --- /dev/null +++ b/benchmark/range_bsearch_endpointless.yml @@ -0,0 +1,21 @@ +prelude: | + re = (1..) + rb = (..0) + +benchmark: + 'endless 10**0': re.bsearch { |x| x >= 1 } + 'endless 10**1': re.bsearch { |x| x >= 10 } + 'endless 10**2': re.bsearch { |x| x >= 100 } + 'endless 10**3': re.bsearch { |x| x >= 1000 } + 'endless 10**4': re.bsearch { |x| x >= 10000 } + 'endless 10**5': re.bsearch { |x| x >= 100000 } + 'endless 10**10': re.bsearch { |x| x >= 10000000000 } + 'endless 10**100': re.bsearch { |x| x >= 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 } + 'beginless -10**0': rb.bsearch { |x| x >= -1 } + 'beginless -10**1': rb.bsearch { |x| x >= -10 } + 'beginless -10**2': rb.bsearch { |x| x >= -100 } + 'beginless -10**3': rb.bsearch { |x| x >= -1000 } + 'beginless -10**4': rb.bsearch { |x| x >= -10000 } + 'beginless -10**5': rb.bsearch { |x| x >= -100000 } + 'beginless -10**10': rb.bsearch { |x| x >= -10000000000 } + 'beginless -10**100': rb.bsearch { |x| x >= -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 } diff --git a/benchmark/range_bsearch_fixnum.yml b/benchmark/range_bsearch_fixnum.yml new file mode 100644 index 0000000000..59416531b9 --- /dev/null +++ b/benchmark/range_bsearch_fixnum.yml @@ -0,0 +1,10 @@ +prelude: | + first = 1 + last = 10000 + mid = (first + last) / 2 + r = first..last + +benchmark: + first: r.bsearch { |x| x >= first } + mid: r.bsearch { |x| x >= mid } + last: r.bsearch { |x| x >= last } diff --git a/benchmark/range_count.yml b/benchmark/range_count.yml new file mode 100644 index 0000000000..58f53a0236 --- /dev/null +++ b/benchmark/range_count.yml @@ -0,0 +1,11 @@ +prelude: | + r_1 = 1..1 + r_1k = 1..1000 + r_1m = 1..1000000 + r_str = 'a'..'z' + +benchmark: + 'int 1': r_1.count + 'int 1K': r_1k.count + 'int 1M': r_1m.count + string: r_str.count diff --git a/benchmark/range_last.yml b/benchmark/range_last.yml new file mode 100644 index 0000000000..a6674f82ee --- /dev/null +++ b/benchmark/range_last.yml @@ -0,0 +1,4 @@ +benchmark: + - (1..1_000_000).last(100) + - (1..1_000_000).last(1000) + - (1..1_000_000).last(10000) diff --git a/benchmark/range_min.yml b/benchmark/range_min.yml new file mode 100644 index 0000000000..9e60dd7308 --- /dev/null +++ b/benchmark/range_min.yml @@ -0,0 +1,2 @@ +benchmark: + - (1..10).min diff --git a/benchmark/range_overlap.yml b/benchmark/range_overlap.yml new file mode 100644 index 0000000000..700a00053c --- /dev/null +++ b/benchmark/range_overlap.yml @@ -0,0 +1,19 @@ +prelude: | + class Range + unless method_defined?(:overlap?) + def overlap?(other) + other.begin == self.begin || cover?(other.begin) || other.cover?(self.begin) + end + end + end + +benchmark: + - (2..3).overlap?(1..1) + - (2..3).overlap?(2..4) + - (2..3).overlap?(4..5) + - (2..3).overlap?(2..1) + - (2..3).overlap?(0..1) + - (2..3).overlap?(...1) + - (2...3).overlap?(..2) + - (2...3).overlap?(3...) + - (2..3).overlap?('a'..'d') diff --git a/benchmark/range_reverse_each.yml b/benchmark/range_reverse_each.yml new file mode 100644 index 0000000000..a32efeccc6 --- /dev/null +++ b/benchmark/range_reverse_each.yml @@ -0,0 +1,16 @@ +prelude: | + rf_1 = 0..1 + rf_1k = 0..1000 + rf_1m = 0..1000000 + big = 2**1000 + rb_1 = big..big+1 + rb_1k = big..big+1000 + rb_1m = big..big+1000000 + +benchmark: + "Fixnum 1": rf_1.reverse_each { _1 } + "Fixnum 1K": rf_1k.reverse_each { _1 } + "Fixnum 1M": rf_1m.reverse_each { _1 } + "Bignum 1": rb_1.reverse_each { _1 } + "Bignum 1K": rb_1k.reverse_each { _1 } + "Bignum 1M": rb_1m.reverse_each { _1 } diff --git a/benchmark/realpath.yml b/benchmark/realpath.yml new file mode 100644 index 0000000000..6b6a4836b0 --- /dev/null +++ b/benchmark/realpath.yml @@ -0,0 +1,33 @@ +prelude: | + f = File + pwd = Dir.pwd + Dir.mkdir('b') unless f.directory?('b') + f.write('b/a', '') unless f.file?('b/a') + + relative = 'b/a' + absolute = File.join(pwd, relative) + dir = 'b' + file = 'a' + + relative_dir = 'b/c' + absolute_dir = File.join(pwd, relative_dir) + file_dir = 'c' +teardown: | + require 'fileutils' + FileUtils.rm_rf('b') +benchmark: + relative_nil: "f.realpath(relative, nil)" + absolute_nil: "f.realpath(absolute, nil)" + relative_relative: "f.realpath(file, dir)" + absolute_relative: "f.realpath(absolute, dir)" + relative_absolute: "f.realpath(relative, pwd)" + relative_nil_dir: "f.realdirpath(relative_dir, nil)" + absolute_nil_dir: "f.realdirpath(absolute_dir, nil)" + relative_relative_dir: "f.realdirpath(file_dir, dir)" + absolute_relative_dir: "f.realdirpath(absolute_dir, dir)" + relative_absolute_dir: "f.realdirpath(relative_dir, pwd)" + relative_nil_notexist: "f.realpath(relative_dir, nil) rescue nil" + absolute_nil_notexist: "f.realpath(absolute_dir, nil) rescue nil" + relative_relative_notexist: "f.realpath(file_dir, dir) rescue nil" + absolute_relative_notexist: "f.realpath(absolute_dir, dir) rescue nil" + relative_absolute_notexist: "f.realpath(relative_dir, pwd) rescue nil" diff --git a/benchmark/regexp_dup.yml b/benchmark/regexp_dup.yml new file mode 100644 index 0000000000..52f89991cd --- /dev/null +++ b/benchmark/regexp_dup.yml @@ -0,0 +1,6 @@ +prelude: | + str = "a" * 1000 + re = Regexp.new(str) + +benchmark: + dup: re.dup diff --git a/benchmark/regexp_new.yml b/benchmark/regexp_new.yml new file mode 100644 index 0000000000..bc9ab3ca21 --- /dev/null +++ b/benchmark/regexp_new.yml @@ -0,0 +1,7 @@ +prelude: | + str = "a" * 1000 + re = Regexp.new(str) + +benchmark: + string: Regexp.new(str) + regexp: Regexp.new(re) diff --git a/benchmark/report.rb b/benchmark/report.rb deleted file mode 100644 index d2dc56b1e1..0000000000 --- a/benchmark/report.rb +++ /dev/null @@ -1,79 +0,0 @@ -# -# YARV benchmark driver -# - -require 'yarvutil' -require 'benchmark' -require 'rbconfig' - -def exec_command type, file, w - <<-EOP - $DRIVER_PATH = '#{File.dirname($0)}' - $LOAD_PATH.replace $LOAD_PATH | #{$LOAD_PATH.inspect} - require 'benchmark' - require 'yarvutil' -# print '#{type}' - begin - puts Benchmark.measure{ - #{w}('#{file}') - }.utime - rescue Exception => exec_command_error_variable - puts "\t" + exec_command_error_variable.message - end - EOP -end - -def benchmark cmd - rubybin = ENV['RUBY'] || RbConfig.ruby - - IO.popen(rubybin, 'r+'){|io| - io.write cmd - io.close_write - return io.gets - } -end - -def ruby_exec file - prog = exec_command 'ruby', file, 'load' - benchmark prog -end - -def yarv_exec file - prog = exec_command 'yarv', file, 'YARVUtil.load_bm' - benchmark prog -end - -$wr = $wy = nil - -def measure bench - file = File.dirname($0) + "/bm_#{bench}.rb" - r = ruby_exec(file).to_f - y = yarv_exec(file).to_f - puts "#{bench}\t#{r}\t#{y}" -end - -def measure2 - r = ruby_exec.to_f - y = yarv_exec.to_f - puts r/y -end - -if $0 == __FILE__ - %w{ - whileloop - whileloop2 - times - const - method - poly_method - block - rescue - rescue2 - }.each{|bench| - measure bench - } -end - - - - diff --git a/benchmark/require.yml b/benchmark/require.yml new file mode 100644 index 0000000000..09f218cf08 --- /dev/null +++ b/benchmark/require.yml @@ -0,0 +1,32 @@ +prelude: | + require "fileutils" + + def prepare + num_files = 10000 + + basename = File.dirname($0) + data_dir = File.join(basename, "bm_require.data") + + # skip if all of files exists + if File.exist?(File.join(data_dir, "c#{num_files}.rb")) + return + end + + FileUtils.mkdir_p(data_dir) + + 1.upto(num_files) do |i| + File.write("#{data_dir}/c#{i}.rb", "class C#{i}\n""end\n") + end + end + + prepare +benchmark: + require: | + $:.push File.join(File.dirname(__FILE__), "bm_require.data") + + 1.upto(10000) do |i| + require "c#{i}" + end + + $:.pop +loop_count: 1 diff --git a/benchmark/require_thread.yml b/benchmark/require_thread.yml new file mode 100644 index 0000000000..0c63257106 --- /dev/null +++ b/benchmark/require_thread.yml @@ -0,0 +1,40 @@ +prelude: | + require "fileutils" + + def prepare + num_files = 10000 + + basename = File.dirname($0) + data_dir = File.join(basename, "bm_require.data") + + # skip if all of files exists + if File.exist?(File.join(data_dir, "c#{num_files}.rb")) + return + end + + FileUtils.mkdir_p(data_dir) + + 1.upto(num_files) do |i| + File.write("#{data_dir}/c#{i}.rb", "class C#{i}\n""end\n") + end + end + + prepare +benchmark: + require_thread: | + $:.push File.join(File.dirname(__FILE__), "bm_require.data") + + i=0 + t = Thread.new do + while true + i = i+1 # dummy loop + end + end + + 1.upto(100) do |i| + require "c#{i}" + end + + $:.pop + t.kill +loop_count: 1 diff --git a/benchmark/run.rb b/benchmark/run.rb deleted file mode 100644 index 0cd2363849..0000000000 --- a/benchmark/run.rb +++ /dev/null @@ -1,127 +0,0 @@ -# -# Ruby benchmark driver -# - -require 'benchmark' -require 'rbconfig' - -$matzrubyonly = false -$rubyonly = false - -$results = [] - -# prepare 'wc.input' -def prepare_wc_input - wcinput = File.join(File.dirname($0), 'wc.input') - wcbase = File.join(File.dirname($0), 'wc.input.base') - unless FileTest.exist?(wcinput) - data = File.read(wcbase) - 13.times{ - data << data - } - open(wcinput, 'w'){|f| f.write data} - end -end - -prepare_wc_input - -def bm file - prog = File.readlines(file).map{|e| e.rstrip}.join("\n") - return if prog.empty? - - /[a-z]+_(.+)\.rb/ =~ file - bm_name = $1 - puts '-----------------------------------------------------------' unless $rubyonly || $matzrubyonly - puts "#{bm_name}: " - - -puts <<EOS unless $matzrubyonly || $rubyonly -#{prog} --- -EOS - begin - result = [bm_name] - result << matzruby_exec(file) unless $rubyonly - result << ruby_exec(file) unless $matzrubyonly - $results << result - - rescue Exception => e - puts - puts "** benchmark failure: #{e}" - puts e.backtrace - end -end - -def benchmark file, bin - m = Benchmark.measure{ - `#{bin} #{$opts} #{file}` - } - sec = '%.3f' % m.real - puts " #{sec}" - sec -end - -def ruby_exec file - print 'ruby' - benchmark file, $ruby_program -end - -def matzruby_exec file - print 'matz' - rubylib = ENV['RUBYLIB'] - ENV['RUBYLIB'] = '' - r = benchmark file, $matzruby_program - ENV['RUBYLIB'] = rubylib - r -end - -if $0 == __FILE__ - ARGV.each{|arg| - case arg - when /\A--ruby=(.+)/ - $ruby_program = $1 - when /\A--matzruby=(.+)/ - $matzruby_program = $1 - when /\A--opts=(.+)/ - $opts = $1 - when /\A(-r|--only-ruby)\z/ - $rubyonly = true - when /\A(-m|--only-matzruby)\z/ - $matzrubyonly = true - end - } - ARGV.delete_if{|arg| - /\A-/ =~ arg - } - - puts "MatzRuby:" - system("#{$matzruby_program} -v") - puts "Ruby:" - system("#{$ruby_program} -v") - puts - - if ARGV.empty? - Dir.glob(File.dirname(__FILE__) + '/bm_*.rb').sort.each{|file| - bm file - } - else - ARGV.each{|file| - Dir.glob(File.join(File.dirname(__FILE__), file + '*')){|ef| - # file = "#{File.dirname(__FILE__)}/#{file}.rb" - bm ef - } - } - end - - puts - puts "-- benchmark summary ---------------------------" - $results.each{|res| - print res.shift, "\t" - (res||[]).each{|result| - /([\d\.]+)/ =~ result - print $1 + "\t" if $1 - } - puts - } -end - diff --git a/benchmark/runc.rb b/benchmark/runc.rb deleted file mode 100644 index 97c5cef045..0000000000 --- a/benchmark/runc.rb +++ /dev/null @@ -1,27 +0,0 @@ -# -# -# - -require 'benchmark' -require 'rbconfig' - -$rubybin = ENV['RUBY'] || RbConfig.ruby - -def runfile file - puts file - file = File.join(File.dirname($0), 'contrib', file) - Benchmark.bm{|x| - x.report('ruby'){ - system("#{$rubybin} #{file}") - } - x.report('yarv'){ - system("#{$rubybin} -rite -I.. #{file}") - } - } -end - -ARGV.each{|file| - runfile file -} - - diff --git a/benchmark/scan.yaml b/benchmark/scan.yaml new file mode 100644 index 0000000000..62ad1d6862 --- /dev/null +++ b/benchmark/scan.yaml @@ -0,0 +1,16 @@ +prelude: | + $LOAD_PATH.unshift(File.expand_path("lib")) + require "strscan" + str = "test string" + scanner = StringScanner.new(str) + str = "test" + reg = /test/ +benchmark: + check(reg): | + scanner.check(reg) + check(str): | + scanner.check(str) + match?(reg): | + scanner.match?(reg) + match?(str): | + scanner.match?(str) diff --git a/benchmark/search.yaml b/benchmark/search.yaml new file mode 100644 index 0000000000..42a50c90e6 --- /dev/null +++ b/benchmark/search.yaml @@ -0,0 +1,16 @@ +prelude: | + $LOAD_PATH.unshift(File.expand_path("lib")) + require "strscan" + str = "test string" + scanner = StringScanner.new(str) + str = "string" + reg = /string/ +benchmark: + check_until(reg): | + scanner.check_until(reg) + check_until(str): | + scanner.check_until(str) + exist?(reg): | + scanner.exist?(reg) + exist?(str): | + scanner.exist?(str) diff --git a/benchmark/securerandom.rb b/benchmark/securerandom.rb new file mode 100644 index 0000000000..a082ea6d5b --- /dev/null +++ b/benchmark/securerandom.rb @@ -0,0 +1,5 @@ +require "securerandom" + +20_0000.times do + SecureRandom.random_number(100) +end diff --git a/benchmark/set.yml b/benchmark/set.yml new file mode 100644 index 0000000000..061509cb1f --- /dev/null +++ b/benchmark/set.yml @@ -0,0 +1,261 @@ +prelude: | + # First 1000 digits of pi + pi = <<~END.gsub(/\D/, '') + 31415926535897932384626433832795028841971693993751058209749445923078164062862089 + 98628034825342117067982148086513282306647093844609550582231725359408128481117450 + 28410270193852110555964462294895493038196442881097566593344612847564823378678316 + 52712019091456485669234603486104543266482133936072602491412737245870066063155881 + 74881520920962829254091715364367892590360011330530548820466521384146951941511609 + 43305727036575959195309218611738193261179310511854807446237996274956735188575272 + 48912279381830119491298336733624406566430860213949463952247371907021798609437027 + 70539217176293176752384674818467669405132000568127145263560827785771342757789609 + 17363717872146844090122495343014654958537105079227968925892354201995611212902196 + 08640344181598136297747713099605187072113499999983729780499510597317328160963185 + 95024459455346908302642522308253344685035261931188171010003137838752886587533208 + 38142061717766914730359825349042875546873115956286388235378759375195778185778053 + 21712268066130019278766111959092164201989380952572010654505906988788448549 + END + array1 = 10.times.flat_map do |i| + pi[i...].chars.each_slice(10).map(&:join) + end + array2 = array1.map(&:reverse) + array1.map!(&:to_i) + array2.map!(&:to_i) + a1 = array1[...10] + a2 = array1[...100] + a3 = array1 + oa1 = array2[...10] + oa2 = array2[...100] + oa3 = array2 + s0 = Set.new + s0 = Set.new + s1 = Set.new(a1) + s2 = Set.new(a2) + s3 = Set.new(a3) + o0 = Set.new + o1 = Set.new(array2[...10]) + o2 = Set.new(array2[...100]) + o3 = Set.new(array2) + d0 = s0.dup + d1 = s1.dup + d2 = s2.dup + d3 = s3.dup + ss1 = s1 - a1[-1..-1] + ss2 = s2 - a2[-1..-1] + ss3 = s3 - a3[-1..-1] + os1 = o1 - oa1[-1..-1] + os2 = o2 - oa2[-1..-1] + os3 = o3 - oa3[-1..-1] + member = a1.first + cbi = s0.dup.compare_by_identity + ns = Set[s3, o3, d3] + set_subclass = Class.new(Set) + +benchmark: + new_0: Set.new + new_10: Set.new(a1) + new_100: Set.new(a2) + new_1000: Set.new(a3) + aref_0: Set[] + aref_10: Set[*a1] + aref_100: Set[*a2] + aref_1000: Set[*a3] + amp_0: s0 & o0 + amp_10: s1 & o1 + amp_100: s2 & o2 + amp_1000: s3 & o3 + amp_same_0: s0 & d0 + amp_same_10: s1 & d1 + amp_same_100: s2 & d2 + amp_same_1000: s3 & d3 + minus_0: s0 - o0 + minus_10: s1 - o1 + minus_100: s2 - o2 + minus_1000: s3 - o3 + minus_same_0: s0 - d0 + minus_same_10: s1 - d1 + minus_same_100: s2 - d2 + minus_same_1000: s3 - d3 + spaceship_0: s0 <=> o0 + spaceship_diff_10: s1 <=> o1 + spaceship_diff_100: s2 <=> o2 + spaceship_diff_1000: s2 <=> o3 + spaceship_sub_10: s1 <=> ss1 + spaceship_sub_100: s2 <=> ss2 + spaceship_sub_1000: s2 <=> ss3 + spaceship_sup_10: ss1 <=> s1 + spaceship_sup_100: ss2 <=> s2 + spaceship_sup_1000: ss2 <=> s3 + eq_0: s0 == o0 + eq_10: s1 == o1 + eq_100: s2 == o2 + eq_1000: s3 == o3 + eq_same_0: s0 == d0 + eq_same_10: s1 == d1 + eq_same_100: s2 == d2 + eq_same_1000: s3 == d3 + xor_0: s0 ^ o0 + xor_10: s1 ^ o1 + xor_100: s2 ^ o2 + xor_1000: s3 ^ o3 + xor_same_0: s0 ^ d0 + xor_same_10: s1 ^ d1 + xor_same_100: s2 ^ d2 + xor_same_1000: s3 ^ d3 + pipe_0: s0 | o0 + pipe_10: s1 | o1 + pipe_100: s2 | o2 + pipe_1000: s3 | o3 + pipe_same_0: s0 | d0 + pipe_same_10: s1 | d1 + pipe_same_100: s2 | d2 + pipe_same_1000: s3 | d3 + add: a3.each { s0.add(it) } + add_exist: a3.each { s3.add(it) } + addq: a3.each { s0.add?(it) } + addq_exist: a3.each { s3.add?(it) } + classify_0: s0.classify { it } + classify_10: s1.classify { it & 2 } + classify_100: s2.classify { it & 8 } + classify_1000: s3.classify { it & 32 } + clear: s0.clear + collect_0: s0.collect! { it } + collect_10: s1.collect! { it } + collect_100: s2.collect! { it } + collect_1000: s3.collect! { it } + compare_by_identity_0: s0.dup.compare_by_identity + compare_by_identity_10: s1.dup.compare_by_identity + compare_by_identity_100: s2.dup.compare_by_identity + compare_by_identity_1000: s3.dup.compare_by_identity + compare_by_identityq_false: s0.compare_by_identity? + compare_by_identityq_true: cbi.compare_by_identity? + clone_0: s0.clone + clone_10: s1.clone + clone_100: s2.clone + clone_1000: s3.clone + delete: a3.each { s3.delete(it) } + delete_not_exist: a3.each { o3.delete(it) } + deleteq: a3.each { s3.delete?(it) } + deleteq_not_exist: a3.each { o3.delete?(it) } + delete_if_0: s0.delete_if { it } + delete_if_10: s1.delete_if { it & 2 == 0 } + delete_if_100: s2.delete_if { it & 2 == 0 } + delete_if_1000: s3.delete_if { it & 2 == 0 } + disjoint_0: s0.disjoint? o0 + disjoint_10: s1.disjoint? o1 + disjoint_100: s2.disjoint? o2 + disjoint_1000: s3.disjoint? o3 + disjoint_same_0: s0.disjoint? d0 + disjoint_same_10: s1.disjoint? d1 + disjoint_same_100: s2.disjoint? d2 + disjoint_same_1000: s3.disjoint? d3 + divide_1arity_0: s0.divide { true } + divide_1arity_10: s1.divide { it & 2 } + divide_1arity_100: s2.divide { it & 8 } + divide_1arity_1000: s3.divide { it & 32 } + divide_2arity_0: s0.divide { true } + divide_2arity_10: s1.divide { (_1 & 2) == (_2 & 2) } + divide_2arity_100: s2.divide { (_1 & 8) == (_2 & 8) } + divide_2arity_1000: s3.divide { (_1 & 32) == (_2 & 32) } + dup_0: s0.dup + dup_10: s1.dup + dup_100: s2.dup + dup_1000: s3.dup + each_0: s0.each { it } + each_10: s1.each { it } + each_100: s2.each { it } + each_1000: s3.each { it } + empty_true: s0.empty? + empty_false: s3.empty? + flatten: ns.flatten + flattenb: ns.flatten! + include_true_0: s0.include? member + include_true_10: s1.include? member + include_true_100: s2.include? member + include_true_1000: s3.include? member + include_false_0: s0.include?(-1) + include_false_10: s1.include?(-1) + include_false_100: s2.include?(-1) + include_false_1000: s3.include?(-1) + intersect_0: s0.intersect? o0 + intersect_10: s1.intersect? o1 + intersect_100: s2.intersect? o2 + intersect_1000: s3.intersect? o3 + intersect_same_0: s0.intersect? d0 + intersect_same_10: s1.intersect? d1 + intersect_same_100: s2.intersect? d2 + intersect_same_1000: s3.intersect? d3 + join_0: s0.join + join_10: s1.join + join_100: s2.join + join_1000: s3.join + join_arg_0: s0.join "" + join_arg_10: s1.join "" + join_arg_100: s2.join "" + join_arg_1000: s3.join "" + keep_if_0: s0.keep_if { it } + keep_if_10: s1.keep_if { it & 2 == 0 } + keep_if_100: s2.keep_if { it & 2 == 0 } + keep_if_1000: s3.keep_if { it & 2 == 0 } + merge_set: s0.dup.merge(s3, o3) + merge_enum: s0.dup.merge(array1, array2) + proper_subset_0: s0.proper_subset? s0 + proper_subset_10: s1.proper_subset? ss1 + proper_subset_100: s2.proper_subset? ss2 + proper_subset_1000: s3.proper_subset? ss3 + proper_subset_false_10: s1.proper_subset? os1 + proper_subset_false_100: s2.proper_subset? os2 + proper_subset_false_1000: s3.proper_subset? os3 + proper_superset_0: s0.proper_superset? s0 + proper_superset_10: ss1.proper_superset? s1 + proper_superset_100: ss2.proper_superset? s2 + proper_superset_1000: ss3.proper_superset? s3 + proper_superset_false_10: os1.proper_superset? s1 + proper_superset_false_100: os2.proper_superset? s2 + proper_superset_false_1000: os3.proper_superset? s3 + reject_0: s0.reject! { it } + reject_10: s1.reject! { it & 2 == 0 } + reject_100: s2.reject! { it & 2 == 0 } + reject_1000: s3.reject! { it & 2 == 0 } + replace_0: s = Set.new; array1.each { s.replace(s0) } + replace_10: s = Set.new; array1.each { s.replace(s1) } + replace_100: s = Set.new; array1.each { s.replace(s2) } + replace_1000: s = Set.new; array1.each { s.replace(s3) } + reset_0: s0.reset + reset_10: s1.reset + reset_100: s2.reset + reset_1000: s3.reset + select_0: s0.select! { it } + select_10: s1.select! { it & 2 == 0 } + select_100: s2.select! { it & 2 == 0 } + select_1000: s3.select! { it & 2 == 0 } + size_0: s0.size + size_10: s1.size + size_100: s2.size + size_1000: s3.size + subtract_set: s3.dup.subtract(os3) + subtract_enum: s3.dup.subtract(oa3) + subtract_same_set: s3.dup.subtract(s3) + subtract_same_enum: s3.dup.subtract(a3) + subset_0: s0.subset? s0 + subset_10: s1.subset? ss1 + subset_100: s2.subset? ss2 + subset_1000: s3.subset? ss3 + subset_false_10: s1.subset? os1 + subset_false_100: s2.subset? os2 + subset_false_1000: s3.subset? os3 + superset_0: s0.superset? s0 + superset_10: ss1.superset? s1 + superset_100: ss2.superset? s2 + superset_1000: ss3.superset? s3 + superset_false_10: os1.superset? s1 + superset_false_100: os2.superset? s2 + superset_false_1000: os3.superset? s3 + to_a_0: s0.to_a + to_a_10: s1.to_a + to_a_100: s2.to_a + to_a_1000: s3.to_a + to_set_0: s0.to_set + to_set_10: s1.to_set + to_set_100: s2.to_set + to_set_1000: s3.to_set diff --git a/benchmark/bm_so_ackermann.rb b/benchmark/so_ackermann.rb index 7db5be9050..4effa1ecaf 100644 --- a/benchmark/bm_so_ackermann.rb +++ b/benchmark/so_ackermann.rb @@ -1,5 +1,5 @@ #!/usr/bin/ruby -# -*- mode: ruby -*- +# -*- Ruby -*- # $Id: ackermann-ruby.code,v 1.4 2004/11/13 07:40:41 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ diff --git a/benchmark/bm_so_array.rb b/benchmark/so_array.rb index 2b8fce8f99..767e03db5f 100644 --- a/benchmark/bm_so_array.rb +++ b/benchmark/so_array.rb @@ -1,5 +1,5 @@ #!/usr/bin/ruby -# -*- mode: ruby -*- +# -*- Ruby -*- # $Id: ary-ruby.code,v 1.4 2004/11/13 07:41:27 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ # with help from Paul Brannan and Mark Hubbart diff --git a/benchmark/bm_so_binary_trees.rb b/benchmark/so_binary_trees.rb index b1693e4109..b1693e4109 100644 --- a/benchmark/bm_so_binary_trees.rb +++ b/benchmark/so_binary_trees.rb diff --git a/benchmark/bm_so_concatenate.rb b/benchmark/so_concatenate.rb index 873214de7c..4468e20ac8 100644 --- a/benchmark/bm_so_concatenate.rb +++ b/benchmark/so_concatenate.rb @@ -1,5 +1,5 @@ #!/usr/bin/ruby -# -*- mode: ruby -*- +# -*- Ruby -*- # $Id: strcat-ruby.code,v 1.4 2004/11/13 07:43:28 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ # based on code from Aristarkh A Zagorodnikov and Dat Nguyen diff --git a/benchmark/wc.input.base b/benchmark/so_count_words.yml index 41143fbac0..f7322a8541 100644 --- a/benchmark/wc.input.base +++ b/benchmark/so_count_words.yml @@ -1,25 +1,66 @@ -Subject: Re: Who was Izchak Miller? -From: "Jane D. Anonymous" <nobody@yale.edu> -Date: 1996/04/28 -Message-Id: <4lv7bc$oh@news.ycc.yale.edu> -References: <317C405E.5DFA@panix.com> <4lk6vl$gde@ns.oar.net> -To: 75176.2330@compuserve.com -Content-Type: text/plain; charset=us-ascii -Organization: Yale University -X-Url: news:4lk6vl$gde@ns.oar.net -Mime-Version: 1.0 -Newsgroups: rec.games.roguelike.nethack -X-Mailer: Mozilla 1.1N (Macintosh; I; 68K) - -Hello there, Izchak Miller was my father. When I was younger I spent -many a night, hunched over the keyboard with a cup of tea, playing -nethack with him and my brother. my dad was a philosopher with a strong -weakness for fantasy/sci fi. I remember when he started to get involved -with the Nethack team- my brother's Dungeons and Dragons monster book -found a regular place beside my dad's desk. it's nice to see him living -on in the game he loved so much :-). - Tamar Miller - -The following is a really long word of 5000 characters: - -wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww +prelude: | + #!/usr/bin/ruby + + wc_input_base = <<EOS + Subject: Re: Who was Izchak Miller? + From: "Jane D. Anonymous" <nobody@yale.edu> + Date: 1996/04/28 + Message-Id: <4lv7bc$oh@news.ycc.yale.edu> + References: <317C405E.5DFA@panix.com> <4lk6vl$gde@ns.oar.net> + To: 75176.2330@compuserve.com + Content-Type: text/plain; charset=us-ascii + Organization: Yale University + X-Url: news:4lk6vl$gde@ns.oar.net + Mime-Version: 1.0 + Newsgroups: rec.games.roguelike.nethack + X-Mailer: Mozilla 1.1N (Macintosh; I; 68K) + + Hello there, Izchak Miller was my father. When I was younger I spent + many a night, hunched over the keyboard with a cup of tea, playing + nethack with him and my brother. my dad was a philosopher with a strong + weakness for fantasy/sci fi. I remember when he started to get involved + with the Nethack team- my brother's Dungeons and Dragons monster book + found a regular place beside my dad's desk. it's nice to see him living + on in the game he loved so much :-). + Tamar Miller + + The following is a really long word of 5000 characters: + + wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww + EOS + + # prepare 'wc.input' + + def prepare_wc_input(wcbase) + wcinput = File.join(File.dirname($0), 'wc.input') + unless FileTest.exist?(wcinput) + data = wcbase.dup + 13.times{ + data << data + } + File.write(wcinput, data) + end + at_exit {File.unlink(wcinput) rescue nil} + end + + prepare_wc_input(wc_input_base) + +benchmark: + so_count_words: | + # $Id: wc-ruby.code,v 1.4 2004/11/13 07:43:32 bfulgham Exp $ + # http://www.bagley.org/~doug/shootout/ + # with help from Paul Brannan + + nl = nw = nc = 0 + File.open(File.join(File.dirname($0), 'wc.input'), 'rb') do |input| + while tmp = input.read(4096) + data = tmp << (input.gets || "") + nc += data.length + nl += data.count("\n") + ((data.strip! || data).tr!("\n", " ") || data).squeeze! + nw += data.count(" ") + 1 + end + end + # STDERR.puts "#{nl} #{nw} #{nc}" + +loop_count: 1 diff --git a/benchmark/bm_so_exception.rb b/benchmark/so_exception.rb index deb003a594..eb205b4df1 100644 --- a/benchmark/bm_so_exception.rb +++ b/benchmark/so_exception.rb @@ -1,5 +1,5 @@ #!/usr/bin/ruby -# -*- mode: ruby -*- +# -*- Ruby -*- # $Id: except-ruby.code,v 1.4 2004/11/13 07:41:33 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ diff --git a/benchmark/bm_so_fannkuch.rb b/benchmark/so_fannkuch.rb index bac5ecd44c..bac5ecd44c 100644 --- a/benchmark/bm_so_fannkuch.rb +++ b/benchmark/so_fannkuch.rb diff --git a/benchmark/bm_so_fasta.rb b/benchmark/so_fasta.rb index 3f759ba7ae..dcc6b39507 100644 --- a/benchmark/bm_so_fasta.rb +++ b/benchmark/so_fasta.rb @@ -3,7 +3,7 @@ # Contributed by Sokolov Yura $last = 42.0 -def gen_random (max,im=139968,ia=3877,ic=29573) +def gen_random(max, im=139968, ia=3877, ic=29573) (max * ($last = ($last * ia + ic) % im)) / im end diff --git a/benchmark/so_k_nucleotide.yml b/benchmark/so_k_nucleotide.yml new file mode 100644 index 0000000000..d7df086c39 --- /dev/null +++ b/benchmark/so_k_nucleotide.yml @@ -0,0 +1,155 @@ +prelude: | + bm_so_fasta = <<'EOS' + # The Computer Language Shootout + # http://shootout.alioth.debian.org/ + # Contributed by Sokolov Yura + + $last = 42.0 + def gen_random(max, im=139968, ia=3877, ic=29573) + (max * ($last = ($last * ia + ic) % im)) / im + end + + alu = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"+ + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"+ + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"+ + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"+ + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"+ + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"+ + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA" + + iub = [ + ["a", 0.27], + ["c", 0.12], + ["g", 0.12], + ["t", 0.27], + + ["B", 0.02], + ["D", 0.02], + ["H", 0.02], + ["K", 0.02], + ["M", 0.02], + ["N", 0.02], + ["R", 0.02], + ["S", 0.02], + ["V", 0.02], + ["W", 0.02], + ["Y", 0.02], + ] + homosapiens = [ + ["a", 0.3029549426680], + ["c", 0.1979883004921], + ["g", 0.1975473066391], + ["t", 0.3015094502008], + ] + + def make_repeat_fasta(id, desc, src, n) + puts ">#{id} #{desc}" + v = nil + width = 60 + l = src.length + s = src * ((n / l) + 1) + s.slice!(n, l) + puts(s.scan(/.{1,#{width}}/).join("\n")) + end + + def make_random_fasta(id, desc, table, n) + puts ">#{id} #{desc}" + rand, v = nil,nil + width = 60 + chunk = 1 * width + prob = 0.0 + table.each{|v| v[1]= (prob += v[1])} + for i in 1..(n/width) + puts((1..width).collect{ + rand = gen_random(1.0) + table.find{|v| v[1]>rand}[0] + }.join) + end + if n%width != 0 + puts((1..(n%width)).collect{ + rand = gen_random(1.0) + table.find{|v| v[1]>rand}[0] + }.join) + end + end + + + n = (ARGV[0] or 250_000).to_i + + make_repeat_fasta('ONE', 'Homo sapiens alu', alu, n*2) + make_random_fasta('TWO', 'IUB ambiguity codes', iub, n*3) + make_random_fasta('THREE', 'Homo sapiens frequency', homosapiens, n*5) + EOS +benchmark: + - name: so_k_nucleotide + prelude: | + script = File.join(File.dirname($0), 'bm_so_fasta.rb') + File.write(script, bm_so_fasta) + + def prepare_fasta_output n + filebase = File.join(File.dirname($0), 'fasta.output') + script = File.join(File.dirname($0), 'bm_so_fasta.rb') + file = "#{filebase}.#{n}" + + unless FileTest.exist?(file) + STDERR.puts "preparing #{file}" + + open(file, 'w'){|f| + ARGV[0] = n + $stdout = f + load script + $stdout = STDOUT + } + end + end + prepare_fasta_output(100_000) + script: | + # The Computer Language Shootout + # http://shootout.alioth.debian.org + # + # contributed by jose fco. gonzalez + # modified by Sokolov Yura + + seq = String.new + + def frecuency( seq,length ) + n, table = seq.length - length + 1, Hash.new(0) + f, i = nil, nil + (0 ... length).each do |f| + (f ... n).step(length) do |i| + table[seq[i,length]] += 1 + end + end + [n,table] + + end + + def sort_by_freq( seq,length ) + n,table = frecuency( seq,length ) + a, b, v = nil, nil, nil + table.sort{|a,b| b[1] <=> a[1]}.each do |v| + puts "%s %.3f" % [v[0].upcase,((v[1]*100).to_f/n)] + end + puts + end + + def find_seq( seq,s ) + n,table = frecuency( seq,s.length ) + puts "#{table[s].to_s}\t#{s.upcase}" + end + + input = open(File.join(File.dirname($0), 'fasta.output.100000'), 'rb') + + line = input.gets while line !~ /^>THREE/ + line = input.gets + + while (line !~ /^>/) & line do + seq << line.chomp + line = input.gets + end + + [1,2].each {|i| sort_by_freq( seq,i ) } + + %w(ggt ggta ggtatt ggtattttaatt ggtattttaatttatagt).each{|s| find_seq( seq,s) } + loop_count: 1 diff --git a/benchmark/bm_so_lists.rb b/benchmark/so_lists.rb index e8f4a2a5f7..e8f4a2a5f7 100644 --- a/benchmark/bm_so_lists.rb +++ b/benchmark/so_lists.rb diff --git a/benchmark/bm_so_mandelbrot.rb b/benchmark/so_mandelbrot.rb index 76331c64b8..76331c64b8 100644 --- a/benchmark/bm_so_mandelbrot.rb +++ b/benchmark/so_mandelbrot.rb diff --git a/benchmark/bm_so_matrix.rb b/benchmark/so_matrix.rb index e2c5c8e559..2d1e72bda9 100644 --- a/benchmark/bm_so_matrix.rb +++ b/benchmark/so_matrix.rb @@ -1,5 +1,5 @@ #!/usr/bin/ruby -# -*- mode: ruby -*- +# -*- Ruby -*- # $Id: matrix-ruby.code,v 1.4 2004/11/13 07:42:14 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ diff --git a/benchmark/bm_so_meteor_contest.rb b/benchmark/so_meteor_contest.rb index b8e93bd150..d8c8e3ab9c 100644 --- a/benchmark/bm_so_meteor_contest.rb +++ b/benchmark/so_meteor_contest.rb @@ -155,7 +155,7 @@ class Rotation # given a set of directions places the piece (as defined by a set of directions) on the board at # a location that will not take it off the edge - def get_values ( directions ) + def get_values( directions ) start = start_adjust(directions) values = [ start ] directions.each do | direction | @@ -260,7 +260,7 @@ end # support function that create three utility maps: # $converter -- for each row an array that maps a five bit row (via array mapping) -# to the a a five bit representation of the bits below it +# to the a five bit representation of the bits below it # $bit_count -- maps a five bit row (via array mapping) to the number of 1s in the row # @@new_regions -- maps a five bit row (via array mapping) to an array of "region" arrays # a region array has three values the first is a mask of bits in the region, @@ -447,7 +447,7 @@ end # as an inverse. The inverse will ALWAYS be 3 one of the piece configurations that is exactly 3 rotations away # (an odd number). Checking even vs odd then produces a higher probability of finding more pieces earlier # in the cycle. We still need to keep checking all the permutations, but our probability of finding one will -# diminsh over time. Since we are TOLD how many to search for this lets us exit before checking all pieces +# diminish over time. Since we are TOLD how many to search for this lets us exit before checking all pieces # this bennifit is very great when seeking small numbers of solutions and is 0 when looking for more than the # maximum number def find_top( rotation_skip) @@ -467,7 +467,7 @@ def find_top( rotation_skip) end # the normail find routine, iterates through the available pieces, checks all rotations at the current location -# and adds any boards found. depth is acheived via recursion. the overall approach is described +# and adds any boards found. depth is achieved via recursion. the overall approach is described # here: http://www-128.ibm.com/developerworks/java/library/j-javaopt/ # parameters: # start_location -- where to start looking for place for the next piece at @@ -561,4 +561,3 @@ create_collector_support @boards_found = 0 find_all ######## DO IT!!! - diff --git a/benchmark/bm_so_nbody.rb b/benchmark/so_nbody.rb index d6c5bb9e61..9884fc4edc 100644 --- a/benchmark/bm_so_nbody.rb +++ b/benchmark/so_nbody.rb @@ -12,38 +12,38 @@ def _puts *args end class Planet - attr_accessor :x, :y, :z, :vx, :vy, :vz, :mass + attr_accessor :x, :y, :z, :vx, :vy, :vz, :mass - def initialize(x, y, z, vx, vy, vz, mass) - @x, @y, @z = x, y, z - @vx, @vy, @vz = vx * DAYS_PER_YEAR, vy * DAYS_PER_YEAR, vz * DAYS_PER_YEAR - @mass = mass * SOLAR_MASS - end - - def move_from_i(bodies, nbodies, dt, i) - while i < nbodies - b2 = bodies[i] - dx = @x - b2.x - dy = @y - b2.y - dz = @z - b2.z - - distance = Math.sqrt(dx * dx + dy * dy + dz * dz) - mag = dt / (distance * distance * distance) - b_mass_mag, b2_mass_mag = @mass * mag, b2.mass * mag - - @vx -= dx * b2_mass_mag - @vy -= dy * b2_mass_mag - @vz -= dz * b2_mass_mag - b2.vx += dx * b_mass_mag - b2.vy += dy * b_mass_mag - b2.vz += dz * b_mass_mag - i += 1 + def initialize(x, y, z, vx, vy, vz, mass) + @x, @y, @z = x, y, z + @vx, @vy, @vz = vx * DAYS_PER_YEAR, vy * DAYS_PER_YEAR, vz * DAYS_PER_YEAR + @mass = mass * SOLAR_MASS end - @x += dt * @vx - @y += dt * @vy - @z += dt * @vz - end + def move_from_i(bodies, nbodies, dt, i) + while i < nbodies + b2 = bodies[i] + dx = @x - b2.x + dy = @y - b2.y + dz = @z - b2.z + + distance = Math.sqrt(dx * dx + dy * dy + dz * dz) + mag = dt / (distance * distance * distance) + b_mass_mag, b2_mass_mag = @mass * mag, b2.mass * mag + + @vx -= dx * b2_mass_mag + @vy -= dy * b2_mass_mag + @vz -= dz * b2_mass_mag + b2.vx += dx * b_mass_mag + b2.vy += dy * b_mass_mag + b2.vz += dz * b_mass_mag + i += 1 + end + + @x += dt * @vx + @y += dt * @vy + @z += dt * @vz + end end def energy(bodies) diff --git a/benchmark/bm_so_nested_loop.rb b/benchmark/so_nested_loop.rb index a0513f8c47..766fcf7b84 100644 --- a/benchmark/bm_so_nested_loop.rb +++ b/benchmark/so_nested_loop.rb @@ -1,5 +1,5 @@ #!/usr/bin/ruby -# -*- mode: ruby -*- +# -*- Ruby -*- # $Id: nestedloop-ruby.code,v 1.4 2004/11/13 07:42:22 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ # from Avi Bryant diff --git a/benchmark/bm_so_nsieve.rb b/benchmark/so_nsieve.rb index a65cc78233..a65cc78233 100644 --- a/benchmark/bm_so_nsieve.rb +++ b/benchmark/so_nsieve.rb diff --git a/benchmark/bm_so_nsieve_bits.rb b/benchmark/so_nsieve_bits.rb index 6f958ee44e..6f958ee44e 100644 --- a/benchmark/bm_so_nsieve_bits.rb +++ b/benchmark/so_nsieve_bits.rb diff --git a/benchmark/bm_so_object.rb b/benchmark/so_object.rb index e8607c7199..131f44624c 100644 --- a/benchmark/bm_so_object.rb +++ b/benchmark/so_object.rb @@ -1,5 +1,5 @@ #!/usr/bin/ruby -# -*- mode: ruby -*- +# -*- Ruby -*- # $Id: objinst-ruby.code,v 1.4 2004/11/13 07:42:25 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ # with help from Aristarkh Zagorodnikov diff --git a/benchmark/bm_so_partial_sums.rb b/benchmark/so_partial_sums.rb index 630b45cb8d..630b45cb8d 100644 --- a/benchmark/bm_so_partial_sums.rb +++ b/benchmark/so_partial_sums.rb diff --git a/benchmark/bm_so_pidigits.rb b/benchmark/so_pidigits.rb index c7d6fbfb4d..9a537b2d1c 100644 --- a/benchmark/bm_so_pidigits.rb +++ b/benchmark/so_pidigits.rb @@ -38,7 +38,7 @@ end class Transformation attr_reader :q, :r, :s, :t - def initialize (q, r, s, t) + def initialize(q, r, s, t) @q,@r,@s,@t,@k = q,r,s,t,0 end diff --git a/benchmark/bm_so_random.rb b/benchmark/so_random.rb index a66b9e8e63..a66b9e8e63 100644 --- a/benchmark/bm_so_random.rb +++ b/benchmark/so_random.rb diff --git a/benchmark/so_reverse_complement.yml b/benchmark/so_reverse_complement.yml new file mode 100644 index 0000000000..de05eedfc4 --- /dev/null +++ b/benchmark/so_reverse_complement.yml @@ -0,0 +1,137 @@ +prelude: | + bm_so_fasta = <<'EOS' + # The Computer Language Shootout + # http://shootout.alioth.debian.org/ + # Contributed by Sokolov Yura + + $last = 42.0 + def gen_random(max, im=139968, ia=3877, ic=29573) + (max * ($last = ($last * ia + ic) % im)) / im + end + + alu = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"+ + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"+ + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"+ + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"+ + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"+ + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"+ + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA" + + iub = [ + ["a", 0.27], + ["c", 0.12], + ["g", 0.12], + ["t", 0.27], + + ["B", 0.02], + ["D", 0.02], + ["H", 0.02], + ["K", 0.02], + ["M", 0.02], + ["N", 0.02], + ["R", 0.02], + ["S", 0.02], + ["V", 0.02], + ["W", 0.02], + ["Y", 0.02], + ] + homosapiens = [ + ["a", 0.3029549426680], + ["c", 0.1979883004921], + ["g", 0.1975473066391], + ["t", 0.3015094502008], + ] + + def make_repeat_fasta(id, desc, src, n) + puts ">#{id} #{desc}" + v = nil + width = 60 + l = src.length + s = src * ((n / l) + 1) + s.slice!(n, l) + puts(s.scan(/.{1,#{width}}/).join("\n")) + end + + def make_random_fasta(id, desc, table, n) + puts ">#{id} #{desc}" + rand, v = nil,nil + width = 60 + chunk = 1 * width + prob = 0.0 + table.each{|v| v[1]= (prob += v[1])} + for i in 1..(n/width) + puts((1..width).collect{ + rand = gen_random(1.0) + table.find{|v| v[1]>rand}[0] + }.join) + end + if n%width != 0 + puts((1..(n%width)).collect{ + rand = gen_random(1.0) + table.find{|v| v[1]>rand}[0] + }.join) + end + end + + + n = (ARGV[0] or 250_000).to_i + + make_repeat_fasta('ONE', 'Homo sapiens alu', alu, n*2) + make_random_fasta('TWO', 'IUB ambiguity codes', iub, n*3) + make_random_fasta('THREE', 'Homo sapiens frequency', homosapiens, n*5) + EOS +benchmark: + - name: so_reverse_complement + prelude: | + script = File.join(File.dirname($0), 'bm_so_fasta.rb') + File.write(script, bm_so_fasta) + + def prepare_fasta_output n + filebase = File.join(File.dirname($0), 'fasta.output') + script = File.join(File.dirname($0), 'bm_so_fasta.rb') + file = "#{filebase}.#{n}" + + unless FileTest.exist?(file) + STDERR.puts "preparing #{file}" + + open(file, 'w'){|f| + ARGV[0] = n + $stdout = f + load script + $stdout = STDOUT + } + end + end + prepare_fasta_output(2_500_000) + script: | + # The Great Computer Language Shootout + # http://shootout.alioth.debian.org/ + # + # Contributed by Peter Bjarke Olsen + # Modified by Doug King + + seq=Array.new + + def revcomp(seq) + seq.reverse!.tr!('wsatugcyrkmbdhvnATUGCYRKMBDHVN','WSTAACGRYMKVHDBNTAACGRYMKVHDBN') + stringlen=seq.length + 0.step(stringlen-1,60) {|x| print seq.slice(x,60) , "\n"} + end + + input = open(File.join(File.dirname($0), 'fasta.output.2500000'), 'rb') + + while input.gets + if $_ =~ />/ + if seq.length != 0 + revcomp(seq.join) + seq=Array.new + end + puts $_ + else + $_.sub(/\n/,'') + seq.push $_ + end + end + revcomp(seq.join) + loop_count: 1 diff --git a/benchmark/bm_so_sieve.rb b/benchmark/so_sieve.rb index 43dc302648..43dc302648 100644 --- a/benchmark/bm_so_sieve.rb +++ b/benchmark/so_sieve.rb diff --git a/benchmark/bm_so_spectralnorm.rb b/benchmark/so_spectralnorm.rb index 6b97206689..6b97206689 100644 --- a/benchmark/bm_so_spectralnorm.rb +++ b/benchmark/so_spectralnorm.rb diff --git a/benchmark/string_capitalize.yml b/benchmark/string_capitalize.yml new file mode 100644 index 0000000000..7d23fd3d35 --- /dev/null +++ b/benchmark/string_capitalize.yml @@ -0,0 +1,10 @@ +prelude: | + str1 = [*"a".."m",*"N".."Z",*"0".."9"].join("") + str10 = str1 * 10 + str100 = str10 * 10 + str1000 = str100 * 10 +benchmark: + capitalize-1: str1.capitalize + capitalize-10: str10.capitalize + capitalize-100: str100.capitalize + capitalize-1000: str1000.capitalize diff --git a/benchmark/string_casecmp.yml b/benchmark/string_casecmp.yml new file mode 100644 index 0000000000..88a3555c8a --- /dev/null +++ b/benchmark/string_casecmp.yml @@ -0,0 +1,28 @@ +prelude: | + lstr1 = [*"a".."z",*"0".."9"].join("") + lstr10 = lstr1 * 10 + lstr100 = lstr10 * 10 + lstr1000 = lstr100 * 10 + lnonascii1 = [*"\u{e0}".."\u{ff}"].join("") + lnonascii10 = lnonascii1 * 10 + lnonascii100 = lnonascii10 * 10 + lnonascii1000 = lnonascii100 * 10 + ustr1 = [*"A".."Z",*"0".."9"].join("") + ustr10 = ustr1 * 10 + ustr100 = ustr10 * 10 + ustr1000 = ustr100 * 10 + unonascii1 = [*"\u{c0}".."\u{df}"].join("") + unonascii10 = unonascii1 * 10 + unonascii100 = unonascii10 * 10 + unonascii1000 = unonascii100 * 10 +benchmark: + casecmp-1: lstr1.casecmp(ustr1) + casecmp-10: lstr10.casecmp(ustr10) + casecmp-100: lstr100.casecmp(ustr100) + casecmp-1000: lstr1000.casecmp(ustr1000) + casecmp-1000vs10: lstr1000.casecmp(ustr10) + casecmp-nonascii1: lnonascii1.casecmp(unonascii1) + casecmp-nonascii10: lnonascii10.casecmp(unonascii10) + casecmp-nonascii100: lnonascii100.casecmp(unonascii100) + casecmp-nonascii1000: lnonascii1000.casecmp(unonascii1000) + casecmp-nonascii1000vs10: lnonascii1000.casecmp(unonascii10) diff --git a/benchmark/string_casecmp_p.yml b/benchmark/string_casecmp_p.yml new file mode 100644 index 0000000000..a790ce7d55 --- /dev/null +++ b/benchmark/string_casecmp_p.yml @@ -0,0 +1,26 @@ +prelude: | + lstr1 = [*"a".."z",*"0".."9"].join("") + lstr10 = lstr1 * 10 + lstr100 = lstr10 * 10 + lstr1000 = lstr100 * 10 + lnonascii1 = [*"\u{e0}".."\u{ff}"].join("") + lnonascii10 = lnonascii1 * 10 + lnonascii100 = lnonascii10 * 10 + lnonascii1000 = lnonascii100 * 10 + ustr1 = [*"A".."Z",*"0".."9"].join("") + ustr10 = ustr1 * 10 + ustr100 = ustr10 * 10 + ustr1000 = ustr100 * 10 + unonascii1 = [*"\u{c0}".."\u{df}"].join("") + unonascii10 = unonascii1 * 10 + unonascii100 = unonascii10 * 10 + unonascii1000 = unonascii100 * 10 +benchmark: + casecmp_p-1: lstr1.casecmp?(ustr1) + casecmp_p-10: lstr10.casecmp?(ustr10) + casecmp_p-100: lstr100.casecmp?(ustr100) + casecmp_p-1000: lstr1000.casecmp?(ustr1000) + casecmp_p-nonascii1: lnonascii1.casecmp?(unonascii1) + casecmp_p-nonascii10: lnonascii10.casecmp?(unonascii10) + casecmp_p-nonascii100: lnonascii100.casecmp?(unonascii100) + casecmp_p-nonascii1000: lnonascii1000.casecmp?(unonascii1000) diff --git a/benchmark/string_concat.yml b/benchmark/string_concat.yml new file mode 100644 index 0000000000..f11f95ee9a --- /dev/null +++ b/benchmark/string_concat.yml @@ -0,0 +1,51 @@ +prelude: | + CHUNK = "a" * 64 + UCHUNK = "é" * 32 + SHORT = "a" * (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] / 2) + LONG = "a" * (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 2) + GC.disable # GC causes a lot of variance +benchmark: + binary_concat_7bit: | + buffer = String.new(capacity: 4096, encoding: Encoding::BINARY) + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + utf8_concat_7bit: | + buffer = String.new(capacity: 4096, encoding: Encoding::UTF_8) + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + utf8_concat_UTF8: | + buffer = String.new(capacity: 4096, encoding: Encoding::UTF_8) + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK + interpolation: | + buffer = "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ + "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" + interpolation_same_heap: | + buffer = "#{SHORT}#{SHORT}" + interpolation_switching_heaps: | + buffer = "#{SHORT}#{LONG}" diff --git a/benchmark/string_downcase.yml b/benchmark/string_downcase.yml new file mode 100644 index 0000000000..1fea6afbec --- /dev/null +++ b/benchmark/string_downcase.yml @@ -0,0 +1,18 @@ +prelude: | + str1 = [*"A".."Z",*"0".."9"].join("") + str10 = str1 * 10 + str100 = str10 * 10 + str1000 = str100 * 10 + nonascii1 = [*"\u{c0}".."\u{df}"].join("") + nonascii10 = nonascii1 * 10 + nonascii100 = nonascii10 * 10 + nonascii1000 = nonascii100 * 10 +benchmark: + downcase-1: str1.upcase + downcase-10: str10.upcase + downcase-100: str100.upcase + downcase-1000: str1000.upcase + downcase-nonascii1: nonascii1.downcase + downcase-nonascii10: nonascii10.downcase + downcase-nonascii100: nonascii100.downcase + downcase-nonascii1000: nonascii1000.downcase diff --git a/benchmark/string_dup.yml b/benchmark/string_dup.yml new file mode 100644 index 0000000000..90793f9f2a --- /dev/null +++ b/benchmark/string_dup.yml @@ -0,0 +1,7 @@ +prelude: | + # frozen_string_literal: true +benchmark: + uplus: | + +"A" + dup: | + "A".dup diff --git a/benchmark/string_fstring.yml b/benchmark/string_fstring.yml new file mode 100644 index 0000000000..cafef1f3fe --- /dev/null +++ b/benchmark/string_fstring.yml @@ -0,0 +1,16 @@ +benchmark: + fstring_random: | + i = 0 + str = "same".dup + while i < 5_000_000 + -(i.to_s.freeze) + i += 1 + end + fstring_same: | + i = 0 + str = "same".dup + while i < 10_000_000 + -str + i += 1 + end +loop_count: 1 diff --git a/benchmark/string_gsub.yml b/benchmark/string_gsub.yml new file mode 100644 index 0000000000..0f964337dd --- /dev/null +++ b/benchmark/string_gsub.yml @@ -0,0 +1,43 @@ +prelude: | + # frozen_string_literal: true + STR = ((("a" * 31) + "<") * 1000).freeze + STR_UNICODE = ((("a" * 30) + "\u2028") * 1000).freeze + ESCAPED_CHARS_BINARY = { + "\u2028".b => '\u2028'.b, + "\u2029".b => '\u2029'.b, + ">".b => '\u003e'.b.freeze, + "<".b => '\u003c'.b.freeze, + "&".b => '\u0026'.b.freeze, + } + BINARY_PATTERN = Regexp.union(ESCAPED_CHARS_BINARY.keys) + + ESCAPED_CHARS = { + "\u2028" => '\u2028', + "\u2029" => '\u2029', + ">" => '\u003e', + "<" => '\u003c', + "&" => '\u0026', + } + ESCAPE_PATTERN = Regexp.union(ESCAPED_CHARS.keys) + + +benchmark: + escape: | + str = STR.dup + str.gsub!(ESCAPE_PATTERN, ESCAPED_CHARS) + str + + escape_bin: | + str = STR.b + str.gsub!(BINARY_PATTERN, ESCAPED_CHARS_BINARY) + str.force_encoding(Encoding::UTF_8) + + escape_utf8: | + str = STR_UNICODE.dup + str.gsub!(ESCAPE_PATTERN, ESCAPED_CHARS) + str + + escape_utf8_bin: | + str = STR_UNICODE.b + str.gsub!(BINARY_PATTERN, ESCAPED_CHARS_BINARY) + str.force_encoding(Encoding::UTF_8) diff --git a/benchmark/string_index.rb b/benchmark/string_index.rb new file mode 100644 index 0000000000..7783111082 --- /dev/null +++ b/benchmark/string_index.rb @@ -0,0 +1,3 @@ +str1 = "あ" * 1024 + "い" # not single byte optimizable +str2 = "い" +100_000.times { str1.index(str2) } diff --git a/benchmark/string_rpartition.yml b/benchmark/string_rpartition.yml new file mode 100644 index 0000000000..37e9d1b071 --- /dev/null +++ b/benchmark/string_rpartition.yml @@ -0,0 +1,18 @@ +prelude: | + str1 = [*"a".."z",*"0".."9"].join("") + str10 = str1 * 10 + ":" + str100 = str1 * 100 + ":" + str1000 = str1 * 1000 + ":" + nonascii1 = [*"\u{e0}".."\u{ff}"].join("") + nonascii10 = nonascii1 * 10 + ":" + nonascii100 = nonascii1 * 100 + ":" + nonascii1000 = nonascii1 * 1000 + ":" +benchmark: + rpartition-1: str1.rpartition(":") + rpartition-10: str10.rpartition(":") + rpartition-100: str100.rpartition(":") + rpartition-1000: str1000.rpartition(":") + rpartition-nonascii1: nonascii1.rpartition(":") + rpartition-nonascii10: nonascii10.rpartition(":") + rpartition-nonascii100: nonascii100.rpartition(":") + rpartition-nonascii1000: nonascii1000.rpartition(":") diff --git a/benchmark/string_scan_re.rb b/benchmark/string_scan_re.rb new file mode 100644 index 0000000000..b0d60201a9 --- /dev/null +++ b/benchmark/string_scan_re.rb @@ -0,0 +1,2 @@ +str = Array.new(1_000, 'abc').join(',') +1_000.times { str.scan(/abc/) } diff --git a/benchmark/string_scan_str.rb b/benchmark/string_scan_str.rb new file mode 100644 index 0000000000..42440bd948 --- /dev/null +++ b/benchmark/string_scan_str.rb @@ -0,0 +1,2 @@ +str = Array.new(1_000, 'abc').join(',') +1_000.times { str.scan('abc') } diff --git a/benchmark/string_slice.yml b/benchmark/string_slice.yml new file mode 100644 index 0000000000..fc2393c5d1 --- /dev/null +++ b/benchmark/string_slice.yml @@ -0,0 +1,11 @@ +prelude: | + long_string = "x"*1000+"-hår" +benchmark: + regexp-short: | + "x-hår".slice!(/-(.)(.)(.)/, 3) + regexp-long: | + long_string.dup.slice!(/-(.)(.)(.)/, 3) + string-short: | + "x-hår".slice!("r") + string-long: | + long_string.dup.slice!("r") diff --git a/benchmark/string_split.yml b/benchmark/string_split.yml new file mode 100644 index 0000000000..cc2c7d7855 --- /dev/null +++ b/benchmark/string_split.yml @@ -0,0 +1,22 @@ +prelude: | + str1 = [*0..5].join(" ") + " " + str10 = str1 * 10 + str100 = str10 * 10 + str1000 = str100 * 10 +benchmark: + to_chars-1: str1.split('') + to_chars-10: str10.split('') + to_chars-100: str100.split('') + to_chars-1000: str1000.split('') + to_words-1: str1.split(' ') + to_words-10: str10.split(' ') + to_words-100: str100.split(' ') + to_words-1000: str1000.split(' ') + re_chars-1: str1.split(//) + re_chars-10: str10.split(//) + re_chars-100: str100.split(//) + re_chars-1000: str1000.split(//) + re_space-1: str1.split(/ /) + re_space-10: str10.split(/ /) + re_space-100: str100.split(/ /) + re_space-1000: str1000.split(/ /) diff --git a/benchmark/string_swapcase.yml b/benchmark/string_swapcase.yml new file mode 100644 index 0000000000..eeb5928907 --- /dev/null +++ b/benchmark/string_swapcase.yml @@ -0,0 +1,18 @@ +prelude: | + str1 = [*"A".."M",*"n".."z",*"0".."9"].join("") + str10 = str1 * 10 + str100 = str10 * 10 + str1000 = str100 * 10 + nonascii1 = [*"\u{c0}".."\u{cf}",*"\u{f0}".."\u{ff}"].join("") + nonascii10 = nonascii1 * 10 + nonascii100 = nonascii10 * 10 + nonascii1000 = nonascii100 * 10 +benchmark: + swapcase-1: str1.swapcase + swapcase-10: str10.swapcase + swapcase-100: str100.swapcase + swapcase-1000: str1000.swapcase + swapcase-nonascii1: nonascii1.swapcase + swapcase-nonascii10: nonascii10.swapcase + swapcase-nonascii100: nonascii100.swapcase + swapcase-nonascii1000: nonascii1000.swapcase diff --git a/benchmark/string_upcase.yml b/benchmark/string_upcase.yml new file mode 100644 index 0000000000..dab84bbde2 --- /dev/null +++ b/benchmark/string_upcase.yml @@ -0,0 +1,18 @@ +prelude: | + str1 = [*"a".."z",*"0".."9"].join("") + str10 = str1 * 10 + str100 = str10 * 10 + str1000 = str100 * 10 + nonascii1 = [*"\u{e0}".."\u{ff}"].join("") + nonascii10 = nonascii1 * 10 + nonascii100 = nonascii10 * 10 + nonascii1000 = nonascii100 * 10 +benchmark: + upcase-1: str1.upcase + upcase-10: str10.upcase + upcase-100: str100.upcase + upcase-1000: str1000.upcase + upcase-nonascii1: nonascii1.upcase + upcase-nonascii10: nonascii10.upcase + upcase-nonascii100: nonascii100.upcase + upcase-nonascii1000: nonascii1000.upcase diff --git a/benchmark/struct_accessor.yml b/benchmark/struct_accessor.yml new file mode 100644 index 0000000000..d95240e2dd --- /dev/null +++ b/benchmark/struct_accessor.yml @@ -0,0 +1,37 @@ +prelude: | + C = Struct.new(:x) do + def initialize(...) + super + @ivar = 42 + end + + attr_accessor :ivar + + class_eval <<-END + def r + #{'x;'*256} + end + def w + #{'self.x = nil;'*256} + end + def rm + m = method(:x) + #{'m.call;'*256} + end + def wm + m = method(:x=) + #{'m.call(nil);'*256} + end + def r_ivar + #{'ivar;'*256} + end + END + end + C.new(nil) # ensure common shape is known + obj = C.new(nil) +benchmark: + member_reader: "obj.r" + member_writer: "obj.w" + member_reader_method: "obj.rm" + member_writer_method: "obj.wm" + ivar_reader: "obj.r_ivar" diff --git a/benchmark/time_at.yml b/benchmark/time_at.yml new file mode 100644 index 0000000000..3247efbe77 --- /dev/null +++ b/benchmark/time_at.yml @@ -0,0 +1,7 @@ +prelude: | + # frozen_string_literal: true +benchmark: + - 'Time.at(0)' + - 'Time.at(0, 500)' + - 'Time.at(0, in: "+09:00")' + - 'Time.at(0, 500, in: "+09:00")' diff --git a/benchmark/time_new.yml b/benchmark/time_new.yml new file mode 100644 index 0000000000..5947dd3a41 --- /dev/null +++ b/benchmark/time_new.yml @@ -0,0 +1,4 @@ +benchmark: + - 'Time.new(2021)' + - 'Time.new(2021, 8, 22)' + - 'Time.new(2021, 8, 22, in: "+09:00")' diff --git a/benchmark/time_now.yml b/benchmark/time_now.yml new file mode 100644 index 0000000000..9336877cd4 --- /dev/null +++ b/benchmark/time_now.yml @@ -0,0 +1,4 @@ +benchmark: + - 'Time.now' + - 'Time.now(in: "+09:00")' + - 'Time.now.year' diff --git a/benchmark/time_parse.yml b/benchmark/time_parse.yml new file mode 100644 index 0000000000..6060b58bc6 --- /dev/null +++ b/benchmark/time_parse.yml @@ -0,0 +1,10 @@ +prelude: | + require 'time' + inspect = "2021-08-23 09:57:02 +0900" + iso8601 = "2021-08-23T09:57:02+09:00" +benchmark: + - Time.iso8601(iso8601) + - Time.parse(iso8601) + - Time.parse(inspect) + - Time.new(iso8601) rescue Time.iso8601(iso8601) + - Time.new(inspect) rescue Time.parse(inspect) diff --git a/benchmark/time_strftime.yml b/benchmark/time_strftime.yml new file mode 100644 index 0000000000..28f62aec87 --- /dev/null +++ b/benchmark/time_strftime.yml @@ -0,0 +1,7 @@ +prelude: | + # frozen_string_literal: true + time = Time.now +benchmark: + - time.strftime("%FT%T") # 19B + - time.strftime("%FT%T.%3N") # 23B + - time.strftime("%FT%T.%6N") # 26B diff --git a/benchmark/time_strptime.yml b/benchmark/time_strptime.yml new file mode 100644 index 0000000000..8d89ebb7a7 --- /dev/null +++ b/benchmark/time_strptime.yml @@ -0,0 +1,13 @@ +prelude: | + require 'time' +benchmark: + - Time.strptime("28/Aug/2005:06:54:20 +0000", "%d/%b/%Y:%T %z") + - Time.strptime("1", "%s") + - Time.strptime("0 +0100", "%s %z") + - Time.strptime("0 UTC", "%s %z") + - Time.strptime("1.5", "%s.%N") + - Time.strptime("1.000000000001", "%s.%N") + - Time.strptime("20010203 -0200", "%Y%m%d %z") + - Time.strptime("20010203 UTC", "%Y%m%d %z") + - Time.strptime("2018-365", "%Y-%j") + - Time.strptime("2018-091", "%Y-%j") diff --git a/benchmark/time_subsec.rb b/benchmark/time_subsec.rb new file mode 100644 index 0000000000..505021c701 --- /dev/null +++ b/benchmark/time_subsec.rb @@ -0,0 +1,2 @@ +t = Time.now +4000000.times { t.subsec } diff --git a/benchmark/time_xmlschema.yml b/benchmark/time_xmlschema.yml new file mode 100644 index 0000000000..654e5cfcbc --- /dev/null +++ b/benchmark/time_xmlschema.yml @@ -0,0 +1,27 @@ +prelude: | + # frozen_string_literal + unless Time.method_defined?(:xmlschema) + class Time + def xmlschema(fraction_digits=0) + fraction_digits = fraction_digits.to_i + s = strftime("%FT%T") + if fraction_digits > 0 + s << strftime(".%#{fraction_digits}N") + end + s << (utc? ? 'Z' : strftime("%:z")) + end + end + end + time = Time.now + utc_time = Time.now.utc + fraction_sec = Time.at(123456789.quo(9999999999)).getlocal("+09:00") + future_time = Time.utc(10000) +benchmark: + - time.xmlschema + - utc_time.xmlschema + - time.xmlschema(6) + - utc_time.xmlschema(6) + - time.xmlschema(9) + - utc_time.xmlschema(9) + - fraction_sec.xmlschema(10) + - future_time.xmlschema diff --git a/benchmark/vm_array.yml b/benchmark/vm_array.yml new file mode 100644 index 0000000000..2a177237ef --- /dev/null +++ b/benchmark/vm_array.yml @@ -0,0 +1,4 @@ +benchmark: + vm_array: | + a = [1,2,3,4,5,6,7,8,9,10] +loop_count: 6000000 diff --git a/benchmark/vm_attr_ivar.yml b/benchmark/vm_attr_ivar.yml new file mode 100644 index 0000000000..75b803478e --- /dev/null +++ b/benchmark/vm_attr_ivar.yml @@ -0,0 +1,14 @@ +prelude: | + class C + attr_reader :a, :b + def initialize + @a = nil + @b = nil + end + end + obj = C.new +benchmark: + vm_attr_ivar: | + j = obj.a + k = obj.b +loop_count: 30000000 diff --git a/benchmark/vm_attr_ivar_set.yml b/benchmark/vm_attr_ivar_set.yml new file mode 100644 index 0000000000..a0d379b18a --- /dev/null +++ b/benchmark/vm_attr_ivar_set.yml @@ -0,0 +1,14 @@ +prelude: | + class C + attr_accessor :a, :b + def initialize + @a = nil + @b = nil + end + end + obj = C.new +benchmark: + vm_attr_ivar_set: | + obj.a = 1 + obj.b = 2 +loop_count: 30000000 diff --git a/benchmark/bm_vm3_backtrace.rb b/benchmark/vm_backtrace.rb index 0fbf73e1ca..0fbf73e1ca 100644 --- a/benchmark/bm_vm3_backtrace.rb +++ b/benchmark/vm_backtrace.rb diff --git a/benchmark/vm_bigarray.yml b/benchmark/vm_bigarray.yml new file mode 100644 index 0000000000..8b2d3f3443 --- /dev/null +++ b/benchmark/vm_bigarray.yml @@ -0,0 +1,105 @@ +benchmark: + vm_bigarray: | + a = [ + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + 1,2,3,4,5,6,7,8,9,10, + ] +loop_count: 6000000 diff --git a/benchmark/vm_bighash.yml b/benchmark/vm_bighash.yml new file mode 100644 index 0000000000..4dacfde793 --- /dev/null +++ b/benchmark/vm_bighash.yml @@ -0,0 +1,4 @@ +benchmark: + vm_bighash: | + a = {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, 10=>10, 11=>11, 12=>12, 13=>13, 14=>14, 15=>15, 16=>16, 17=>17, 18=>18, 19=>19, 20=>20, 21=>21, 22=>22, 23=>23, 24=>24, 25=>25, 26=>26, 27=>27, 28=>28, 29=>29, 30=>30, 31=>31, 32=>32, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 38=>38, 39=>39, 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, 60=>60, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67, 68=>68, 69=>69, 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79, 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, 90=>90, 91=>91, 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, 100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, 110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, 120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126, 127=>127, 128=>128, 129=>129, 130=>130, 131=>131, 132=>132, 133=>133, 134=>134, 135=>135, 136=>136, 137=>137, 138=>138, 139=>139, 140=>140, 141=>141, 142=>142, 143=>143, 144=>144, 145=>145, 146=>146, 147=>147, 148=>148, 149=>149, 150=>150, 151=>151, 152=>152, 153=>153, 154=>154, 155=>155, 156=>156, 157=>157, 158=>158, 159=>159, 160=>160, 161=>161, 162=>162, 163=>163, 164=>164, 165=>165, 166=>166, 167=>167, 168=>168, 169=>169, 170=>170, 171=>171, 172=>172, 173=>173, 174=>174, 175=>175, 176=>176, 177=>177, 178=>178, 179=>179, 180=>180, 181=>181, 182=>182, 183=>183, 184=>184, 185=>185, 186=>186, 187=>187, 188=>188, 189=>189, 190=>190, 191=>191, 192=>192, 193=>193, 194=>194, 195=>195, 196=>196, 197=>197, 198=>198, 199=>199, 200=>200, 201=>201, 202=>202, 203=>203, 204=>204, 205=>205, 206=>206, 207=>207, 208=>208, 209=>209, 210=>210, 211=>211, 212=>212, 213=>213, 214=>214, 215=>215, 216=>216, 217=>217, 218=>218, 219=>219, 220=>220, 221=>221, 222=>222, 223=>223, 224=>224, 225=>225, 226=>226, 227=>227, 228=>228, 229=>229, 230=>230, 231=>231, 232=>232, 233=>233, 234=>234, 235=>235, 236=>236, 237=>237, 238=>238, 239=>239, 240=>240, 241=>241, 242=>242, 243=>243, 244=>244, 245=>245, 246=>246, 247=>247, 248=>248, 249=>249, 250=>250, 251=>251, 252=>252, 253=>253, 254=>254, 255=>255, 256=>256, 257=>257, 258=>258, 259=>259, 260=>260, 261=>261, 262=>262, 263=>263, 264=>264, 265=>265, 266=>266, 267=>267, 268=>268, 269=>269, 270=>270, 271=>271, 272=>272, 273=>273, 274=>274, 275=>275, 276=>276, 277=>277, 278=>278, 279=>279, 280=>280, 281=>281, 282=>282, 283=>283, 284=>284, 285=>285, 286=>286, 287=>287, 288=>288, 289=>289, 290=>290, 291=>291, 292=>292, 293=>293, 294=>294, 295=>295, 296=>296, 297=>297, 298=>298, 299=>299, 300=>300, 301=>301, 302=>302, 303=>303, 304=>304, 305=>305, 306=>306, 307=>307, 308=>308, 309=>309, 310=>310, 311=>311, 312=>312, 313=>313, 314=>314, 315=>315, 316=>316, 317=>317, 318=>318, 319=>319, 320=>320, 321=>321, 322=>322, 323=>323, 324=>324, 325=>325, 326=>326, 327=>327, 328=>328, 329=>329, 330=>330, 331=>331, 332=>332, 333=>333, 334=>334, 335=>335, 336=>336, 337=>337, 338=>338, 339=>339, 340=>340, 341=>341, 342=>342, 343=>343, 344=>344, 345=>345, 346=>346, 347=>347, 348=>348, 349=>349, 350=>350, 351=>351, 352=>352, 353=>353, 354=>354, 355=>355, 356=>356, 357=>357, 358=>358, 359=>359, 360=>360, 361=>361, 362=>362, 363=>363, 364=>364, 365=>365, 366=>366, 367=>367, 368=>368, 369=>369, 370=>370, 371=>371, 372=>372, 373=>373, 374=>374, 375=>375, 376=>376, 377=>377, 378=>378, 379=>379, 380=>380, 381=>381, 382=>382, 383=>383, 384=>384, 385=>385, 386=>386, 387=>387, 388=>388, 389=>389, 390=>390, 391=>391, 392=>392, 393=>393, 394=>394, 395=>395, 396=>396, 397=>397, 398=>398, 399=>399, 400=>400, 401=>401, 402=>402, 403=>403, 404=>404, 405=>405, 406=>406, 407=>407, 408=>408, 409=>409, 410=>410, 411=>411, 412=>412, 413=>413, 414=>414, 415=>415, 416=>416, 417=>417, 418=>418, 419=>419, 420=>420, 421=>421, 422=>422, 423=>423, 424=>424, 425=>425, 426=>426, 427=>427, 428=>428, 429=>429, 430=>430, 431=>431, 432=>432, 433=>433, 434=>434, 435=>435, 436=>436, 437=>437, 438=>438, 439=>439, 440=>440, 441=>441, 442=>442, 443=>443, 444=>444, 445=>445, 446=>446, 447=>447, 448=>448, 449=>449, 450=>450, 451=>451, 452=>452, 453=>453, 454=>454, 455=>455, 456=>456, 457=>457, 458=>458, 459=>459, 460=>460, 461=>461, 462=>462, 463=>463, 464=>464, 465=>465, 466=>466, 467=>467, 468=>468, 469=>469, 470=>470, 471=>471, 472=>472, 473=>473, 474=>474, 475=>475, 476=>476, 477=>477, 478=>478, 479=>479, 480=>480, 481=>481, 482=>482, 483=>483, 484=>484, 485=>485, 486=>486, 487=>487, 488=>488, 489=>489, 490=>490, 491=>491, 492=>492, 493=>493, 494=>494, 495=>495, 496=>496, 497=>497, 498=>498, 499=>499, 500=>500,} +loop_count: 60000 diff --git a/benchmark/vm_block.yml b/benchmark/vm_block.yml new file mode 100644 index 0000000000..68b3e40bf5 --- /dev/null +++ b/benchmark/vm_block.yml @@ -0,0 +1,9 @@ +prelude: | + def m + yield + end +benchmark: + vm_block: | + m{ + } +loop_count: 30000000 diff --git a/benchmark/vm_block_handler.yml b/benchmark/vm_block_handler.yml new file mode 100644 index 0000000000..461d7953ad --- /dev/null +++ b/benchmark/vm_block_handler.yml @@ -0,0 +1,27 @@ +# :FIXME: is there a way to benchmark block_handler_type_ifunc? + +prelude: | + p = proc{_1} + o = Object.new + def o.each + i = 0 + while i < 3_000_000 do + yield i + i += 1 + end + end + +benchmark: + - name: block_handler_type_iseq + script: | + o.each{_1} + + - name: block_handler_type_symbol + script: | + o.each(&:itself) + + - name: block_handler_type_proc + script: | + o.each(&p) + +loop_count: 1 diff --git a/benchmark/vm_blockparam.yml b/benchmark/vm_blockparam.yml new file mode 100644 index 0000000000..5e5a0170a2 --- /dev/null +++ b/benchmark/vm_blockparam.yml @@ -0,0 +1,7 @@ +prelude: | + def m &b + end +benchmark: + vm_blockparam: | + m{} +loop_count: 30000000 diff --git a/benchmark/vm_blockparam_call.yml b/benchmark/vm_blockparam_call.yml new file mode 100644 index 0000000000..a7d8d366ea --- /dev/null +++ b/benchmark/vm_blockparam_call.yml @@ -0,0 +1,8 @@ +prelude: | + def m &b + b.call + end +benchmark: + vm_blockparam_call: | + m{} +loop_count: 30000000 diff --git a/benchmark/vm_blockparam_pass.yml b/benchmark/vm_blockparam_pass.yml new file mode 100644 index 0000000000..841f5e7a63 --- /dev/null +++ b/benchmark/vm_blockparam_pass.yml @@ -0,0 +1,12 @@ +prelude: | + def bp_yield + yield + end + + def bp_pass &b + bp_yield &b + end +benchmark: + vm_blockparam_pass: | + bp_pass{} +loop_count: 30000000 diff --git a/benchmark/vm_blockparam_yield.yml b/benchmark/vm_blockparam_yield.yml new file mode 100644 index 0000000000..8ea9b46ed2 --- /dev/null +++ b/benchmark/vm_blockparam_yield.yml @@ -0,0 +1,8 @@ +prelude: | + def bp_yield &b + yield + end +benchmark: + vm_blockparam_yield: | + bp_yield{} +loop_count: 30000000 diff --git a/benchmark/vm_call_bmethod.yml b/benchmark/vm_call_bmethod.yml new file mode 100644 index 0000000000..40136e5aa4 --- /dev/null +++ b/benchmark/vm_call_bmethod.yml @@ -0,0 +1,37 @@ +prelude: | + define_method(:a0){} + define_method(:a1){|a| a} + define_method(:s){|*a| a} + define_method(:b){|kw: 1| kw} + + t0 = 0.times.to_a + t1 = 1.times.to_a + t10 = 10.times.to_a + t100 = 100.times.to_a + kw = {kw: 2} +benchmark: + bmethod_simple_0: | + a0 + bmethod_simple_1: | + a1(1) + bmethod_simple_0_splat: | + a0(*t0) + bmethod_simple_1_splat: | + a1(*t1) + bmethod_no_splat: | + s + bmethod_0_splat: | + s(*t0) + bmethod_1_splat: | + s(*t1) + bmethod_10_splat: | + s(*t10) + bmethod_100_splat: | + s(*t100) + bmethod_kw: | + b(kw: 1) + bmethod_no_kw: | + b + bmethod_kw_splat: | + b(**kw) +loop_count: 6000000 diff --git a/benchmark/vm_call_kw_and_kw_splat.yml b/benchmark/vm_call_kw_and_kw_splat.yml new file mode 100644 index 0000000000..aa6e549e0c --- /dev/null +++ b/benchmark/vm_call_kw_and_kw_splat.yml @@ -0,0 +1,25 @@ +prelude: | + h1, h10, h100, h1000 = [1, 10, 100, 1000].map do |n| + h = {kw: 1} + n.times{|i| h[i.to_s.to_sym] = i} + h + end + eh = {} + def kw(kw: nil, **kws) end +benchmark: + 1: | + kw(**h1) + 1_mutable: | + kw(**eh, **h1) + 10: | + kw(**h10) + 10_mutable: | + kw(**eh, **h10) + 100: | + kw(**h100) + 100_mutable: | + kw(**eh, **h100) + 1000: | + kw(**h1000) + 1000_mutable: | + kw(**eh, **h1000) diff --git a/benchmark/vm_call_method_missing.yml b/benchmark/vm_call_method_missing.yml new file mode 100644 index 0000000000..f890796f11 --- /dev/null +++ b/benchmark/vm_call_method_missing.yml @@ -0,0 +1,62 @@ +prelude: | + class A0 + def method_missing(m); m end + end + class A1 + def method_missing(m, a) a; end + end + class S + def method_missing(m, *a) a; end + end + class B + def method_missing(m, kw: 1) kw end + end + class SB + def method_missing(m, *a, kw: 1) kw end + end + + t0 = 0.times.to_a + t1 = 1.times.to_a + t10 = 10.times.to_a + t200 = 200.times.to_a + kw = {kw: 2} + + a0 = A0.new + a1 = A1.new + s = S.new + b = B.new + sb = SB.new +benchmark: + method_missing_simple_0: | + a0.() + method_missing_simple_1: | + a1.x(1) + method_missing_simple_0_splat: | + a0.(*t0) + method_missing_simple_1_splat: | + a1.(*t1) + method_missing_no_splat: | + s.() + method_missing_0_splat: | + s.(*t0) + method_missing_1_splat: | + s.(*t1) + method_missing_10_splat: | + s.(*t10) + method_missing_200_splat: | + s.(*t200) + method_missing_kw: | + b.(kw: 1) + method_missing_no_kw: | + b.() + method_missing_kw_splat: | + b.(**kw) + method_missing_0_splat_kw: | + sb.(*t0, **kw) + method_missing_1_splat_kw: | + sb.(*t1, **kw) + method_missing_10_splat_kw: | + sb.(*t10, **kw) + method_missing_200_splat_kw: | + sb.(*t200, **kw) +loop_count: 1000000 diff --git a/benchmark/vm_call_send_iseq.yml b/benchmark/vm_call_send_iseq.yml new file mode 100644 index 0000000000..60ff23c475 --- /dev/null +++ b/benchmark/vm_call_send_iseq.yml @@ -0,0 +1,77 @@ +prelude: | + def a0; end + def a1(a) a; end + def s(*a) a; end + def b(kw: 1) kw end + def sb(*a, kw: 1) kw end + + t0 = 0.times.to_a + t1 = 1.times.to_a + t10 = 10.times.to_a + t200 = 200.times.to_a + + a0_t0 = [:a0, *t0] + a1_t1 = [:a1, *t1] + s_t0 = [:s, *t0] + s_t1 = [:s, *t1] + s_t10 = [:s, *t10] + s_t200 = [:s, *t200] + sb_t0 = [:sb, *t0] + sb_t1 = [:sb, *t1] + sb_t10 = [:sb, *t10] + sb_t200 = [:sb, *t200] + kw = {kw: 2} +benchmark: + send_simple_0: | + send(:a0) + send_simple_1: | + send(:a1, 1) + send_simple_0_splat: | + send(:a0, *t0) + send_simple_1_splat: | + send(:a1, *t1) + send_simple_0_splat_comb: | + send(*a0_t0) + send_simple_1_splat_comb: | + send(*a1_t1) + send_no_splat: | + send(:s) + send_0_splat: | + send(:s, *t0) + send_1_splat: | + send(:s, *t1) + send_10_splat: | + send(:s, *t10) + send_200_splat: | + send(:s, *t200) + send_0_splat_comb: | + send(*s_t0) + send_1_splat_comb: | + send(*s_t1) + send_10_splat_comb: | + send(*s_t10) + send_200_splat_comb: | + send(*s_t200) + send_kw: | + send(:b, kw: 1) + send_no_kw: | + send(:b) + send_kw_splat: | + send(:b, **kw) + send_0_splat_kw: | + send(:sb, *t0, **kw) + send_1_splat_kw: | + send(:sb, *t1, **kw) + send_10_splat_kw: | + send(:sb, *t10, **kw) + send_200_splat_kw: | + send(:sb, *t200, **kw) + send_0_splat_comb_kw: | + send(*sb_t0, **kw) + send_1_splat_comb_kw: | + send(*sb_t1, **kw) + send_10_splat_comb_kw: | + send(*sb_t10, **kw) + send_200_splat_comb_kw: | + send(*sb_t200, **kw) +loop_count: 3000000 diff --git a/benchmark/vm_call_symproc.yml b/benchmark/vm_call_symproc.yml new file mode 100644 index 0000000000..16e0ac579e --- /dev/null +++ b/benchmark/vm_call_symproc.yml @@ -0,0 +1,83 @@ +prelude: | + def self.a0; end + def self.a1(a) a; end + def self.s(*a) a; end + def self.b(kw: 1) kw end + def self.sb(*a, kw: 1) kw end + + t0 = 0.times.to_a + t1 = 1.times.to_a + t10 = 10.times.to_a + t200 = 200.times.to_a + + a0_t0 = [self, *t0] + a1_t1 = [self, *t1] + s_t0 = [self, *t0] + s_t1 = [self, *t1] + s_t10 = [self, *t10] + s_t200 = [self, *t200] + sb_t0 = [self, *t0] + sb_t1 = [self, *t1] + sb_t10 = [self, *t10] + sb_t200 = [self, *t200] + kw = {kw: 2} + + a0 = :a0.to_proc + a1 = :a1.to_proc + s = :s.to_proc + b = :b.to_proc + sb = :sb.to_proc +benchmark: + symproc_simple_0: | + a0.(self) + symproc_simple_1: | + a1.(self, 1) + symproc_simple_0_splat: | + a0.(self, *t0) + symproc_simple_1_splat: | + a1.(self, *t1) + symproc_simple_0_splat_comb: | + a0.(*a0_t0) + symproc_simple_1_splat_comb: | + a1.(*a1_t1) + symproc_no_splat: | + s.(self) + symproc_0_splat: | + s.(self, *t0) + symproc_1_splat: | + s.(self, *t1) + symproc_10_splat: | + s.(self, *t10) + symproc_200_splat: | + s.(self, *t200) + symproc_0_splat_comb: | + s.(*s_t0) + symproc_1_splat_comb: | + s.(*s_t1) + symproc_10_splat_comb: | + s.(*s_t10) + symproc_200_splat_comb: | + s.(*s_t200) + symproc_kw: | + b.(self, kw: 1) + symproc_no_kw: | + b.(self) + symproc_kw_splat: | + b.(self, **kw) + symproc_0_splat_kw: | + sb.(self, *t0, **kw) + symproc_1_splat_kw: | + sb.(self, *t1, **kw) + symproc_10_splat_kw: | + sb.(self, *t10, **kw) + symproc_200_splat_kw: | + sb.(self, *t200, **kw) + symproc_0_splat_comb_kw: | + sb.(*sb_t0, **kw) + symproc_1_splat_comb_kw: | + sb.(*sb_t1, **kw) + symproc_10_splat_comb_kw: | + sb.(*sb_t10, **kw) + symproc_200_splat_comb_kw: | + sb.(*sb_t200, **kw) +loop_count: 1000000 diff --git a/benchmark/vm_case.yml b/benchmark/vm_case.yml new file mode 100644 index 0000000000..b26a491a15 --- /dev/null +++ b/benchmark/vm_case.yml @@ -0,0 +1,13 @@ +benchmark: + vm_case: | + case :foo + when :bar + raise + when :baz + raise + when :boo + raise + when :foo + # noop + end +loop_count: 6000000 diff --git a/benchmark/vm_case_classes.yml b/benchmark/vm_case_classes.yml new file mode 100644 index 0000000000..cacc4f0464 --- /dev/null +++ b/benchmark/vm_case_classes.yml @@ -0,0 +1,9 @@ +benchmark: + vm_case_classes: | + case :foo + when Hash + raise + when Array + raise + end +loop_count: 6000000 diff --git a/benchmark/vm_case_lit.yml b/benchmark/vm_case_lit.yml new file mode 100644 index 0000000000..9f91801544 --- /dev/null +++ b/benchmark/vm_case_lit.yml @@ -0,0 +1,23 @@ +# loop_count is not utilized since `i` is involved in the script +benchmark: + vm_case_lit: | + i = 0 + @ret = [ "foo", true, false, :sym, 6, nil, 0.1, 0xffffffffffffffff ] + def foo(i) + @ret[i % @ret.size] + end + + while i<6_000_000 + case foo(i) + when "foo" then :foo + when true then true + when false then false + when :sym then :sym + when 6 then :fix + when nil then nil + when 0.1 then :float + when 0xffffffffffffffff then :big + end + i += 1 + end +loop_count: 1 diff --git a/benchmark/bm_vm3_clearmethodcache.rb b/benchmark/vm_clearmethodcache.rb index 9661323cd2..9661323cd2 100644 --- a/benchmark/bm_vm3_clearmethodcache.rb +++ b/benchmark/vm_clearmethodcache.rb diff --git a/benchmark/vm_const.yml b/benchmark/vm_const.yml new file mode 100644 index 0000000000..8939ca0cd3 --- /dev/null +++ b/benchmark/vm_const.yml @@ -0,0 +1,13 @@ +prelude: | + Const = 1 + A = B = C = D = E = F = G = H = I = J = K = L = M = N = O = P = Q = R = S = T = U = V = W = X = Y = Z = 1 + def foo + A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P; Q; R; S; T; U; V; W; X; Y; Z + end +benchmark: + vm_const: | + j = Const + k = Const + vm_const_many: | + foo +loop_count: 30000000 diff --git a/benchmark/vm_cvar.yml b/benchmark/vm_cvar.yml new file mode 100644 index 0000000000..1d0e161829 --- /dev/null +++ b/benchmark/vm_cvar.yml @@ -0,0 +1,20 @@ +prelude: | + class A + @@foo = 1 + + def self.foo + @@foo + end + + ("A".."Z").each do |module_name| + eval <<-EOM + module #{module_name} + end + + include #{module_name} + EOM + end + end +benchmark: + vm_cvar: A.foo +loop_count: 600000 diff --git a/benchmark/vm_defined_method.yml b/benchmark/vm_defined_method.yml new file mode 100644 index 0000000000..347e0cfd33 --- /dev/null +++ b/benchmark/vm_defined_method.yml @@ -0,0 +1,8 @@ +prelude: | + class Object + define_method(:m){} + end +benchmark: + vm_defined_method: | + m; m; m; m; m; m; m; m; +loop_count: 6000000 diff --git a/benchmark/vm_dstr.yml b/benchmark/vm_dstr.yml new file mode 100644 index 0000000000..30c7a3193c --- /dev/null +++ b/benchmark/vm_dstr.yml @@ -0,0 +1,6 @@ +prelude: | + x = y = 'z' +benchmark: + vm_dstr: | + str = "foo#{x}bar#{y}baz" +loop_count: 6000000 diff --git a/benchmark/bm_vm2_dstr.rb b/benchmark/vm_dstr_ary.rb index 58c0f7bbc3..1d3aa3b97b 100644 --- a/benchmark/bm_vm2_dstr.rb +++ b/benchmark/vm_dstr_ary.rb @@ -1,5 +1,5 @@ i = 0 -x = y = 'z' +x = y = [] while i<6_000_000 # benchmark loop 2 i += 1 str = "foo#{x}bar#{y}baz" diff --git a/benchmark/bm_vm2_method.rb b/benchmark/vm_dstr_bool.rb index a8ccff7138..631ca54755 100644 --- a/benchmark/bm_vm2_method.rb +++ b/benchmark/vm_dstr_bool.rb @@ -1,9 +1,7 @@ -def m - nil -end - i = 0 +x = true +y = false while i<6_000_000 # benchmark loop 2 i += 1 - m; m; m; m; m; m; m; m; + str = "foo#{x}bar#{y}baz" end diff --git a/benchmark/vm_dstr_class_module.rb b/benchmark/vm_dstr_class_module.rb new file mode 100644 index 0000000000..becf0861c7 --- /dev/null +++ b/benchmark/vm_dstr_class_module.rb @@ -0,0 +1,10 @@ +i = 0 +class A; end unless defined?(A) +module B; end unless defined?(B) +x = A +y = B +while i<6_000_000 # benchmark loop 2 + i += 1 + str = "foo#{x}bar#{y}baz" +end + diff --git a/benchmark/vm_dstr_digit.rb b/benchmark/vm_dstr_digit.rb new file mode 100644 index 0000000000..caaa395192 --- /dev/null +++ b/benchmark/vm_dstr_digit.rb @@ -0,0 +1,7 @@ +i = 0 +x = 0 +y = 9 +while i<6_000_000 # benchmark loop 2 + i += 1 + str = "foo#{x}bar#{y}baz" +end diff --git a/benchmark/bm_vm2_eval.rb b/benchmark/vm_dstr_int.rb index 307cfc28ef..ed380d7595 100644 --- a/benchmark/bm_vm2_eval.rb +++ b/benchmark/vm_dstr_int.rb @@ -1,6 +1,5 @@ i = 0 while i<6_000_000 # benchmark loop 2 i += 1 - eval("1") + str = "foo#{i}bar#{i}baz" end - diff --git a/benchmark/vm_dstr_nil.rb b/benchmark/vm_dstr_nil.rb new file mode 100644 index 0000000000..ec4f5d6c67 --- /dev/null +++ b/benchmark/vm_dstr_nil.rb @@ -0,0 +1,6 @@ +i = 0 +x = y = nil +while i<6_000_000 # benchmark loop 2 + i += 1 + str = "foo#{x}bar#{y}baz" +end diff --git a/benchmark/vm_dstr_obj.rb b/benchmark/vm_dstr_obj.rb new file mode 100644 index 0000000000..fb78637ead --- /dev/null +++ b/benchmark/vm_dstr_obj.rb @@ -0,0 +1,6 @@ +i = 0 +x = y = Object.new +while i<6_000_000 # benchmark loop 2 + i += 1 + str = "foo#{x}bar#{y}baz" +end diff --git a/benchmark/vm_dstr_obj_def.rb b/benchmark/vm_dstr_obj_def.rb new file mode 100644 index 0000000000..99ff7b98fb --- /dev/null +++ b/benchmark/vm_dstr_obj_def.rb @@ -0,0 +1,8 @@ +i = 0 +o = Object.new +def o.to_s; -""; end +x = y = o +while i<6_000_000 # benchmark loop 2 + i += 1 + str = "foo#{x}bar#{y}baz" +end diff --git a/benchmark/bm_vm2_array.rb b/benchmark/vm_dstr_str.rb index df9037c83c..45fc107892 100644 --- a/benchmark/bm_vm2_array.rb +++ b/benchmark/vm_dstr_str.rb @@ -1,5 +1,6 @@ i = 0 +x = y = "" while i<6_000_000 # benchmark loop 2 i += 1 - a = [1,2,3,4,5,6,7,8,9,10] + str = "foo#{x}bar#{y}baz" end diff --git a/benchmark/bm_vm2_regexp.rb b/benchmark/vm_dstr_sym.rb index 55f9e957a3..484b8f8150 100644 --- a/benchmark/bm_vm2_regexp.rb +++ b/benchmark/vm_dstr_sym.rb @@ -1,6 +1,6 @@ i = 0 -str = 'xxxhogexxx' +x = y = :z while i<6_000_000 # benchmark loop 2 - /hoge/ =~ str i += 1 + str = "foo#{x}bar#{y}baz" end diff --git a/benchmark/vm_ensure.yml b/benchmark/vm_ensure.yml new file mode 100644 index 0000000000..4ea62f30de --- /dev/null +++ b/benchmark/vm_ensure.yml @@ -0,0 +1,14 @@ +# Not utilizing loop_count since using it for this is too unstable for now +benchmark: + vm_ensure: | + i = 0 + while i<30_000_000 + i += 1 + begin + begin + ensure + end + ensure + end + end +loop_count: 1 diff --git a/benchmark/vm_eval.yml b/benchmark/vm_eval.yml new file mode 100644 index 0000000000..7ba1a8d1de --- /dev/null +++ b/benchmark/vm_eval.yml @@ -0,0 +1,4 @@ +benchmark: + vm_eval: | + eval("1") +loop_count: 6000000 diff --git a/benchmark/vm_fiber_allocate.yml b/benchmark/vm_fiber_allocate.yml new file mode 100644 index 0000000000..b5a54e1ddf --- /dev/null +++ b/benchmark/vm_fiber_allocate.yml @@ -0,0 +1,8 @@ +prelude: | + # Disable GC to see raw throughput: + GC.disable +benchmark: + vm_fiber_allocate: | + fiber = Fiber.new{Fiber.yield} + fiber.resume +loop_count: 100000 diff --git a/benchmark/vm_fiber_count.yml b/benchmark/vm_fiber_count.yml new file mode 100644 index 0000000000..b83d3152d4 --- /dev/null +++ b/benchmark/vm_fiber_count.yml @@ -0,0 +1,10 @@ +# On Linux, you will need to increase the maximum number of memory maps: +# sudo sysctl -w vm.max_map_count=200000 +prelude: | + fibers = [] +benchmark: + vm_fiber_count: | + fiber = Fiber.new{Fiber.yield} + fibers << fiber + fiber.resume +loop_count: 100000 diff --git a/benchmark/vm_fiber_reuse.yml b/benchmark/vm_fiber_reuse.yml new file mode 100644 index 0000000000..4ca41085b1 --- /dev/null +++ b/benchmark/vm_fiber_reuse.yml @@ -0,0 +1,14 @@ +prelude: | + GC.disable + fibers = [] +benchmark: + vm_fiber_reuse: | + 1024.times do + fiber = Fiber.new{Fiber.yield} + fibers << fiber + fiber.resume + end + + fibers.clear + GC.start +loop_count: 200 diff --git a/benchmark/vm_fiber_reuse_gc.yml b/benchmark/vm_fiber_reuse_gc.yml new file mode 100644 index 0000000000..892622f121 --- /dev/null +++ b/benchmark/vm_fiber_reuse_gc.yml @@ -0,0 +1,12 @@ +# https://bugs.ruby-lang.org/issues/16009 +prelude: | + fibers = [] +benchmark: + vm_fiber_reuse_gc: | + 2000.times do + fiber = Fiber.new{Fiber.yield} + fibers << fiber + fiber.resume + end + fibers.clear +loop_count: 100 diff --git a/benchmark/vm_fiber_switch.yml b/benchmark/vm_fiber_switch.yml new file mode 100644 index 0000000000..3de36b66eb --- /dev/null +++ b/benchmark/vm_fiber_switch.yml @@ -0,0 +1,9 @@ +prelude: | + # based on benchmark for [ruby-core:65518] [Feature #10341] by Knut Franke + fib = Fiber.new do + loop { Fiber.yield } + end +benchmark: + vm_fiber_switch: | + fib.resume +loop_count: 20000000 diff --git a/benchmark/vm_float_simple.yml b/benchmark/vm_float_simple.yml new file mode 100644 index 0000000000..92f5fd52ab --- /dev/null +++ b/benchmark/vm_float_simple.yml @@ -0,0 +1,8 @@ +prelude: | + f = 0.0 +benchmark: + vm_float_simple: | + f += 0.1; f -= 0.1 + f += 0.1; f -= 0.1 + f += 0.1; f -= 0.1 +loop_count: 30000000 diff --git a/benchmark/vm_freezeobj.yml b/benchmark/vm_freezeobj.yml new file mode 100644 index 0000000000..69a795a354 --- /dev/null +++ b/benchmark/vm_freezeobj.yml @@ -0,0 +1,6 @@ +prelude: | + objs = 100000.times.map { Object.new } +benchmark: + vm_freeze_obj: | + objs.map(&:freeze) +loop_count: 600 diff --git a/benchmark/vm_freezestring.yml b/benchmark/vm_freezestring.yml new file mode 100644 index 0000000000..facc9aa043 --- /dev/null +++ b/benchmark/vm_freezestring.yml @@ -0,0 +1,10 @@ +prelude: | + class String + def freeze + -self + end + end +benchmark: + vm_freezestring: | + "tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze +loop_count: 6000000 diff --git a/benchmark/bm_vm3_gc.rb b/benchmark/vm_gc.rb index 7db9829d44..e668026915 100755..100644 --- a/benchmark/bm_vm3_gc.rb +++ b/benchmark/vm_gc.rb @@ -1,4 +1,3 @@ -#! /usr/bin/ruby 5000.times do 100.times do {"xxxx"=>"yyyy"} diff --git a/benchmark/vm_gc_old_full.rb b/benchmark/vm_gc_old_full.rb new file mode 100644 index 0000000000..cfdfc8c5a5 --- /dev/null +++ b/benchmark/vm_gc_old_full.rb @@ -0,0 +1,4 @@ +old_object = Array.new(1_000_000){''} +100.times do + GC.start +end diff --git a/benchmark/vm_gc_old_immediate.rb b/benchmark/vm_gc_old_immediate.rb new file mode 100644 index 0000000000..ad22feb655 --- /dev/null +++ b/benchmark/vm_gc_old_immediate.rb @@ -0,0 +1,4 @@ +old_object = Array.new(1_000_000){''} +30_000.times do + GC.start(full_mark: false, immediate_sweep: true) +end diff --git a/benchmark/vm_gc_old_lazy.rb b/benchmark/vm_gc_old_lazy.rb new file mode 100644 index 0000000000..b74d44baf1 --- /dev/null +++ b/benchmark/vm_gc_old_lazy.rb @@ -0,0 +1,4 @@ +old_object = Array.new(1_000_000){''} +30_000.times do + GC.start(full_mark: false, immediate_sweep: false) +end diff --git a/benchmark/vm_gc_short_lived.yml b/benchmark/vm_gc_short_lived.yml new file mode 100644 index 0000000000..29c803fee3 --- /dev/null +++ b/benchmark/vm_gc_short_lived.yml @@ -0,0 +1,9 @@ +benchmark: + vm_gc_short_lived: | + a = '' # short-lived String + b = '' + c = '' + d = '' + e = '' + f = '' +loop_count: 30000000 diff --git a/benchmark/vm_gc_short_with_complex_long.yml b/benchmark/vm_gc_short_with_complex_long.yml new file mode 100644 index 0000000000..4b6c3ed7b9 --- /dev/null +++ b/benchmark/vm_gc_short_with_complex_long.yml @@ -0,0 +1,25 @@ +prelude: | + def nested_hash h, n + if n == 0 + '' + else + 10.times{ + h[Object.new] = nested_hash(h, n-1) + } + end + end + + long_lived = Hash.new + nested_hash long_lived, 6 + + GC.start + GC.start +benchmark: + vm_gc_short_with_complex_long: | + a = '' # short-lived String + b = '' + c = '' + d = '' + e = '' + f = '' +loop_count: 30000000 diff --git a/benchmark/vm_gc_short_with_long.yml b/benchmark/vm_gc_short_with_long.yml new file mode 100644 index 0000000000..03ba0f95a9 --- /dev/null +++ b/benchmark/vm_gc_short_with_long.yml @@ -0,0 +1,13 @@ +prelude: | + long_lived = Array.new(1_000_000){|i| "#{i}"} + GC.start + GC.start +benchmark: + vm_gc_short_with_long: | + a = '' # short-lived String + b = '' + c = '' + d = '' + e = '' + f = '' +loop_count: 30000000 diff --git a/benchmark/vm_gc_short_with_symbol.yml b/benchmark/vm_gc_short_with_symbol.yml new file mode 100644 index 0000000000..129b8bf4ed --- /dev/null +++ b/benchmark/vm_gc_short_with_symbol.yml @@ -0,0 +1,13 @@ +prelude: | + 50_000.times{|i| sym = "sym#{i}".to_sym} + GC.start + GC.start +benchmark: + vm_gc_short_with_symbol: | + a = '' # short-lived String + b = '' + c = '' + d = '' + e = '' + f = '' +loop_count: 30000000 diff --git a/benchmark/vm_gc_wb_ary.yml b/benchmark/vm_gc_wb_ary.yml new file mode 100644 index 0000000000..e3293e72d0 --- /dev/null +++ b/benchmark/vm_gc_wb_ary.yml @@ -0,0 +1,12 @@ +prelude: | + short_lived_ary = [] + + if RUBY_VERSION >= "2.2.0" + GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) + end + + short_lived = '' +benchmark: + vm_gc_wb_ary: | + short_lived_ary[0] = short_lived # write barrier +loop_count: 30000000 diff --git a/benchmark/vm_gc_wb_ary_promoted.yml b/benchmark/vm_gc_wb_ary_promoted.yml new file mode 100644 index 0000000000..003995945b --- /dev/null +++ b/benchmark/vm_gc_wb_ary_promoted.yml @@ -0,0 +1,15 @@ +prelude: | + long_lived = [] + + if RUBY_VERSION > "2.2.0" + 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) } + elsif + GC.start + end + + short_lived = '' + +benchmark: + vm_gc_wb_ary_promoted: | + long_lived[0] = short_lived # write barrier +loop_count: 30000000 diff --git a/benchmark/vm_gc_wb_obj.yml b/benchmark/vm_gc_wb_obj.yml new file mode 100644 index 0000000000..a2a2ce2d18 --- /dev/null +++ b/benchmark/vm_gc_wb_obj.yml @@ -0,0 +1,15 @@ +prelude: | + class C + attr_accessor :foo + end + short_lived_obj = C.new + + if RUBY_VERSION >= "2.2.0" + GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) + end + + short_lived = '' +benchmark: + vm_gc_wb_obj: | + short_lived_obj.foo = short_lived # write barrier +loop_count: 30000000 diff --git a/benchmark/vm_gc_wb_obj_promoted.yml b/benchmark/vm_gc_wb_obj_promoted.yml new file mode 100644 index 0000000000..00a454ba72 --- /dev/null +++ b/benchmark/vm_gc_wb_obj_promoted.yml @@ -0,0 +1,17 @@ +prelude: | + class C + attr_accessor :foo + end + long_lived = C.new + + if RUBY_VERSION >= "2.2.0" + 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) } + elsif + GC.start + end + + short_lived = '' +benchmark: + vm_gc_wb_obj_promoted: | + long_lived.foo = short_lived # write barrier +loop_count: 30000000 diff --git a/benchmark/vm_iclass_super.yml b/benchmark/vm_iclass_super.yml new file mode 100644 index 0000000000..21bb7db247 --- /dev/null +++ b/benchmark/vm_iclass_super.yml @@ -0,0 +1,20 @@ +prelude: | + class C + def m + 1 + end + + ("A".."M").each do |module_name| + eval <<-EOM + module #{module_name} + def m; super; end + end + prepend #{module_name} + EOM + end + end + + obj = C.new +benchmark: + vm_iclass_super: obj.m +loop_count: 6000000 diff --git a/benchmark/vm_ivar.yml b/benchmark/vm_ivar.yml new file mode 100644 index 0000000000..119531d5ef --- /dev/null +++ b/benchmark/vm_ivar.yml @@ -0,0 +1,6 @@ +prelude: "@a = 1\n" +benchmark: + vm_ivar: | + j = @a + k = @a +loop_count: 30000000 diff --git a/benchmark/vm_ivar_embedded_obj_init.yml b/benchmark/vm_ivar_embedded_obj_init.yml new file mode 100644 index 0000000000..74fe20a630 --- /dev/null +++ b/benchmark/vm_ivar_embedded_obj_init.yml @@ -0,0 +1,14 @@ +prelude: | + class C + def set_ivars + @a = nil + @b = nil + @c = nil + end + end + + c = C.new +benchmark: + vm_ivar_embedded_obj_init: | + c.set_ivars +loop_count: 30000000 diff --git a/benchmark/vm_ivar_extended_obj_init.yml b/benchmark/vm_ivar_extended_obj_init.yml new file mode 100644 index 0000000000..f054bab282 --- /dev/null +++ b/benchmark/vm_ivar_extended_obj_init.yml @@ -0,0 +1,16 @@ +prelude: | + class C + def set_ivars + @a = nil + @b = nil + @c = nil + @d = nil + @e = nil + end + end + + c = C.new +benchmark: + vm_ivar_extended_obj_init: | + c.set_ivars +loop_count: 30000000 diff --git a/benchmark/vm_ivar_generic_get.yml b/benchmark/vm_ivar_generic_get.yml new file mode 100644 index 0000000000..dae2d37671 --- /dev/null +++ b/benchmark/vm_ivar_generic_get.yml @@ -0,0 +1,17 @@ +prelude: | + class C < Array + attr_reader :a, :b, :c + def initialize + @a = nil + @b = nil + @c = nil + end + end + + c = C.new +benchmark: + vm_ivar_generic_get: | + c.a + c.b + c.c +loop_count: 30000000 diff --git a/benchmark/vm_ivar_generic_set.yml b/benchmark/vm_ivar_generic_set.yml new file mode 100644 index 0000000000..102a6577fb --- /dev/null +++ b/benchmark/vm_ivar_generic_set.yml @@ -0,0 +1,14 @@ +prelude: | + class C < Array + def set_ivars + @a = nil + @b = nil + @c = nil + end + end + + c = C.new +benchmark: + vm_ivar_generic_set: | + c.set_ivars +loop_count: 30000000 diff --git a/benchmark/vm_ivar_get.yml b/benchmark/vm_ivar_get.yml new file mode 100644 index 0000000000..1e0dad665f --- /dev/null +++ b/benchmark/vm_ivar_get.yml @@ -0,0 +1,100 @@ +prelude: | + class Example + def initialize + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + end + + def get_value_loop + sum = 0 + + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + i += 1 + end + + return sum + end + + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + + def self.get_value_loop + sum = 0 + + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + i += 1 + end + + return sum + end + end + + class GenExample < Time + def initialize + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + end + + def get_value_loop + sum = 0 + + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + i += 1 + end + + return sum + end + end + + obj = Example.new + gen = GenExample.new +benchmark: + vm_ivar_get_on_obj: | + obj.get_value_loop + vm_ivar_get_on_class: | + Example.get_value_loop + vm_ivar_get_on_generic: | + gen.get_value_loop +loop_count: 100 diff --git a/benchmark/vm_ivar_get_unintialized.yml b/benchmark/vm_ivar_get_unintialized.yml new file mode 100644 index 0000000000..a1ccfb06ce --- /dev/null +++ b/benchmark/vm_ivar_get_unintialized.yml @@ -0,0 +1,12 @@ +prelude: | + class Example + def read + @uninitialized + end + end + + obj = Example.new +benchmark: + vm_ivar_get_uninitialized: | + obj.read +loop_count: 30000000 diff --git a/benchmark/vm_ivar_ic_miss.yml b/benchmark/vm_ivar_ic_miss.yml new file mode 100644 index 0000000000..944fb1a9e6 --- /dev/null +++ b/benchmark/vm_ivar_ic_miss.yml @@ -0,0 +1,20 @@ +prelude: | + class Foo + def initialize diverge + if diverge + @a = 1 + end + + @a0 = @a1 = @a2 = @a3 = @a4 = @a5 = @a6 = @a7 = @a8 = @a9 = @a10 = @a11 = @a12 = @a13 = @a14 = @a15 = @a16 = @a17 = @a18 = @a19 = @a20 = @a21 = @a22 = @a23 = @a24 = @a25 = @a26 = @a27 = @a28 = @a29 = @a30 = @a31 = @a32 = @a33 = @a34 = @a35 = @a36 = @a37 = @a38 = @a39 = @a40 = @a41 = @a42 = @a43 = @a44 = @a45 = @a46 = @a47 = @a48 = @a49 = @a50 = @a51 = @a52 = @a53 = @a54 = @a55 = @a56 = @a57 = @a58 = @a59 = @a60 = @a61 = @a62 = @a63 = @a64 = @a65 = @a66 = @a67 = @a68 = @a69 = @a70 = @a71 = @a72 = @a73 = @a74 = @b = 1 + end + + def b; @b; end + end + + a = Foo.new false + b = Foo.new true +benchmark: + vm_ivar_ic_miss: | + a.b + b.b +loop_count: 30000000 diff --git a/benchmark/vm_ivar_lazy_set.yml b/benchmark/vm_ivar_lazy_set.yml new file mode 100644 index 0000000000..7372ffcfbc --- /dev/null +++ b/benchmark/vm_ivar_lazy_set.yml @@ -0,0 +1,12 @@ +prelude: | + class Example + def lazy_set + @uninitialized ||= 123 + end + end + + objs = 10000000.times.map { Example.new } +benchmark: + vm_ivar_lazy_set: | + objs.each(&:lazy_set) +loop_count: 1 diff --git a/benchmark/vm_ivar_memoize.yml b/benchmark/vm_ivar_memoize.yml new file mode 100644 index 0000000000..90f6b07f05 --- /dev/null +++ b/benchmark/vm_ivar_memoize.yml @@ -0,0 +1,85 @@ +prelude: | + IVARS = 60 + class Record + def initialize(offset = false) + @offset = 1 if offset + @first = 0 + IVARS.times do |i| + instance_variable_set("@ivar_#{i}", i) + end + end + + def first + @first + end + + def lazy_set + @lazy_set ||= 123 + end + + def undef + @undef + end + end + + Record.new # Need one alloc to right size + + BASE = Record.new + LAZY = Record.new + LAZY.lazy_set + + class Miss < Record + @first = 0 + IVARS.times do |i| + instance_variable_set("@i_#{i}", i) + end + end + + Miss.new # Need one alloc to right size + MISS = Miss.new + + DIVERGENT = Record.new(true) + +benchmark: + vm_ivar_stable_shape: | + BASE.first + BASE.first + BASE.first + BASE.first + BASE.first + BASE.first + vm_ivar_memoize_unstable_shape: | + BASE.first + LAZY.first + BASE.first + LAZY.first + BASE.first + LAZY.first + vm_ivar_memoize_unstable_shape_miss: | + BASE.first + MISS.first + BASE.first + MISS.first + BASE.first + MISS.first + vm_ivar_unstable_undef: | + BASE.undef + LAZY.undef + BASE.undef + LAZY.undef + BASE.undef + LAZY.undef + vm_ivar_divergent_shape: | + BASE.first + DIVERGENT.first + BASE.first + DIVERGENT.first + BASE.first + DIVERGENT.first + vm_ivar_divergent_shape_imbalanced: | + BASE.first + DIVERGENT.first + DIVERGENT.first + DIVERGENT.first + DIVERGENT.first + DIVERGENT.first diff --git a/benchmark/vm_ivar_of_class.yml b/benchmark/vm_ivar_of_class.yml new file mode 100644 index 0000000000..172e28b2fd --- /dev/null +++ b/benchmark/vm_ivar_of_class.yml @@ -0,0 +1,12 @@ +prelude: | + class C + @a = 1 + def self.a + _a = @a; _a = @a; _a = @a; _a = @a; _a = @a; + _a = @a; _a = @a; _a = @a; _a = @a; _a = @a; + end + end +benchmark: + vm_ivar_of_class: | + a = C.a +loop_count: 30000000 diff --git a/benchmark/vm_ivar_of_class_set.yml b/benchmark/vm_ivar_of_class_set.yml new file mode 100644 index 0000000000..2ea5199423 --- /dev/null +++ b/benchmark/vm_ivar_of_class_set.yml @@ -0,0 +1,11 @@ +prelude: | + class C + @a = 1 + def self.a o + @a = o; @a = o; @a = o; @a = o; @a = o; @a = o; + end + end +benchmark: + vm_ivar_of_class_set: | + a = C.a(nil) +loop_count: 30000000 diff --git a/benchmark/vm_ivar_set.yml b/benchmark/vm_ivar_set.yml new file mode 100644 index 0000000000..8bbb60043b --- /dev/null +++ b/benchmark/vm_ivar_set.yml @@ -0,0 +1,5 @@ +benchmark: + vm_ivar_set: | + @a = 1 + @b = 2 +loop_count: 30000000 diff --git a/benchmark/vm_ivar_set_on_instance.yml b/benchmark/vm_ivar_set_on_instance.yml new file mode 100644 index 0000000000..6ce53a86ec --- /dev/null +++ b/benchmark/vm_ivar_set_on_instance.yml @@ -0,0 +1,94 @@ +prelude: | + class TheClass + def initialize + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + end + + def set_value_loop + # 100k + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + i += 1 + end + end + end + + class Generic < Time + def initialize + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + end + + def set_value_loop + # 100k + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + i += 1 + end + end + end + + obj = TheClass.new + gen_obj = Generic.new + + class SomeClass + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + + def self.set_value_loop + # 100k + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + i += 1 + end + end + end + +benchmark: + vm_ivar_set_on_instance: | + obj.set_value_loop + vm_ivar_set_on_generic: | + gen_obj.set_value_loop + vm_ivar_set_on_class: | + SomeClass.set_value_loop +loop_count: 100 diff --git a/benchmark/vm_ivar_set_subclass.yml b/benchmark/vm_ivar_set_subclass.yml new file mode 100644 index 0000000000..bc8bf5bf6b --- /dev/null +++ b/benchmark/vm_ivar_set_subclass.yml @@ -0,0 +1,20 @@ +prelude: | + class A + def set_ivars + @a = nil + @b = nil + @c = nil + @d = nil + @e = nil + end + end + class B < A; end + class C < A; end + + b = B.new + c = C.new +benchmark: + vm_ivar_init_subclass: | + b.set_ivars + c.set_ivars +loop_count: 3000000 diff --git a/benchmark/vm_length.yml b/benchmark/vm_length.yml new file mode 100644 index 0000000000..5fd94e7d86 --- /dev/null +++ b/benchmark/vm_length.yml @@ -0,0 +1,8 @@ +prelude: | + a = 'abc' + b = [1, 2, 3] +benchmark: + vm_length: | + a.length + b.length +loop_count: 30000000 diff --git a/benchmark/vm_lvar_cond_set.yml b/benchmark/vm_lvar_cond_set.yml new file mode 100644 index 0000000000..1845f9d12e --- /dev/null +++ b/benchmark/vm_lvar_cond_set.yml @@ -0,0 +1,8 @@ +benchmark: + vm_lvar_cond_set: | + a ||= 1 + b ||= 1 + c ||= 1 + d ||= 1 + nil +loop_count: 30000000 diff --git a/benchmark/vm_lvar_init.yml b/benchmark/vm_lvar_init.yml new file mode 100644 index 0000000000..70a9b1c0ca --- /dev/null +++ b/benchmark/vm_lvar_init.yml @@ -0,0 +1,21 @@ +# while loop cost is not removed because `i` is used in the script +benchmark: + vm_lvar_init: | + def m v + unless v + # unreachable code + v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = v10 = + v11 = v12 = v13 = v14 = v15 = v16 = v17 = v18 = v19 = v20 = + v21 = v22 = v23 = v24 = v25 = v26 = v27 = v28 = v29 = v30 = + v31 = v32 = v33 = v34 = v35 = v36 = v37 = v38 = v39 = v40 = + v41 = v42 = v43 = v44 = v45 = v46 = v47 = v48 = v49 = v50 = 1 + end + end + + i = 0 + + while i<30_000_000 + i += 1 + m i + end +loop_count: 1 diff --git a/benchmark/vm_lvar_set.yml b/benchmark/vm_lvar_set.yml new file mode 100644 index 0000000000..f29f763d81 --- /dev/null +++ b/benchmark/vm_lvar_set.yml @@ -0,0 +1,4 @@ +benchmark: + vm_lvar_set: | + a = b = c = d = e = f = g = h = j = k = l = m = n = o = p = q = r = 1 +loop_count: 30000000 diff --git a/benchmark/vm_method.yml b/benchmark/vm_method.yml new file mode 100644 index 0000000000..d45e4ec572 --- /dev/null +++ b/benchmark/vm_method.yml @@ -0,0 +1,8 @@ +prelude: | + def m + nil + end +benchmark: + vm_method: | + m; m; m; m; m; m; m; m; +loop_count: 6000000 diff --git a/benchmark/vm_method_missing.yml b/benchmark/vm_method_missing.yml new file mode 100644 index 0000000000..3da456c0bb --- /dev/null +++ b/benchmark/vm_method_missing.yml @@ -0,0 +1,11 @@ +prelude: | + class C + def method_missing mid + end + end + + obj = C.new +benchmark: + vm_method_missing: | + obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; +loop_count: 6000000 diff --git a/benchmark/vm_method_splat_calls.yml b/benchmark/vm_method_splat_calls.yml new file mode 100644 index 0000000000..f2f366e99c --- /dev/null +++ b/benchmark/vm_method_splat_calls.yml @@ -0,0 +1,13 @@ +prelude: | + def f(x=0, y: 0) end + a = [1] + ea = [] + kw = {y: 1} + b = lambda{} +benchmark: + arg_splat: "f(1, *ea)" + arg_splat_block: "f(1, *ea, &b)" + splat_kw_splat: "f(*a, **kw)" + splat_kw_splat_block: "f(*a, **kw, &b)" + splat_kw: "f(*a, y: 1)" + splat_kw_block: "f(*a, y: 1, &b)" diff --git a/benchmark/vm_method_splat_calls2.yml b/benchmark/vm_method_splat_calls2.yml new file mode 100644 index 0000000000..d33dcd7e8b --- /dev/null +++ b/benchmark/vm_method_splat_calls2.yml @@ -0,0 +1,27 @@ +prelude: | + def named_arg_splat(*a) end + def named_arg_kw_splat(*a, **kw) end + def anon_arg_splat(*) end + def anon_kw_splat(**) end + def anon_arg_kw_splat(*, **) end + def anon_fw_to_named(*, **) named_arg_kw_splat(*, **) end + def fw_to_named(...) named_arg_kw_splat(...) end + def fw_to_anon_to_named(...) anon_fw_to_named(...) end + def fw_no_kw(...) named_arg_splat(...) end + a = [1] + kw = {y: 1} +benchmark: + named_multi_arg_splat: "named_arg_splat(*a, *a)" + named_post_splat: "named_arg_splat(*a, a)" + anon_arg_splat: "anon_arg_splat(*a)" + anon_arg_kw_splat: "anon_arg_kw_splat(*a, **kw)" + anon_multi_arg_splat: "anon_arg_splat(*a, *a)" + anon_post_splat: "anon_arg_splat(*a, a)" + anon_kw_splat: "anon_kw_splat(**kw)" + anon_fw_to_named_splat: "anon_fw_to_named(*a, **kw)" + anon_fw_to_named_no_splat: "anon_fw_to_named(1, y: 1)" + fw_to_named_splat: "fw_to_named(*a, **kw)" + fw_to_named_no_splat: "fw_to_named(1, y: 1)" + fw_to_anon_to_named_splat: "fw_to_anon_to_named(*a, **kw)" + fw_to_anon_to_named_no_splat: "fw_to_anon_to_named(1, y: 1)" + fw_no_kw: "fw_no_kw(1, 2)" diff --git a/benchmark/vm_method_with_block.yml b/benchmark/vm_method_with_block.yml new file mode 100644 index 0000000000..281a481394 --- /dev/null +++ b/benchmark/vm_method_with_block.yml @@ -0,0 +1,8 @@ +prelude: | + def m + nil + end +benchmark: + vm_method_with_block: | + m{}; m{}; m{}; m{}; m{}; m{}; m{}; m{}; +loop_count: 6000000 diff --git a/benchmark/vm_module_ann_const_set.yml b/benchmark/vm_module_ann_const_set.yml new file mode 100644 index 0000000000..243229ba4a --- /dev/null +++ b/benchmark/vm_module_ann_const_set.yml @@ -0,0 +1,4 @@ +benchmark: + vm_module_ann_const_set: | + Module.new.const_set(:X, Module.new) +loop_count: 6000000 diff --git a/benchmark/vm_module_const_set.yml b/benchmark/vm_module_const_set.yml new file mode 100644 index 0000000000..e5a24181a9 --- /dev/null +++ b/benchmark/vm_module_const_set.yml @@ -0,0 +1,8 @@ +prelude: | + module M + end + $VERBOSE = nil +benchmark: + vm_module_const_set: | + M.const_set(:X, Module.new) +loop_count: 6000000 diff --git a/benchmark/vm_mutex.yml b/benchmark/vm_mutex.yml new file mode 100644 index 0000000000..abcf1e28ce --- /dev/null +++ b/benchmark/vm_mutex.yml @@ -0,0 +1,8 @@ +prelude: | + require 'thread' + + m = Thread::Mutex.new +benchmark: + vm_mutex: | + m.synchronize{} +loop_count: 6000000 diff --git a/benchmark/vm_neq.yml b/benchmark/vm_neq.yml new file mode 100644 index 0000000000..fb04d15ae8 --- /dev/null +++ b/benchmark/vm_neq.yml @@ -0,0 +1,7 @@ +prelude: | + obj1 = Object.new + obj2 = Object.new +benchmark: + vm_neq: | + obj1 != obj2 +loop_count: 30000000 diff --git a/benchmark/vm_newlambda.yml b/benchmark/vm_newlambda.yml new file mode 100644 index 0000000000..0b9787d91a --- /dev/null +++ b/benchmark/vm_newlambda.yml @@ -0,0 +1,4 @@ +benchmark: + vm_newlambda: | + lambda {} +loop_count: 6000000 diff --git a/benchmark/vm_not.yml b/benchmark/vm_not.yml new file mode 100644 index 0000000000..c68dde3c50 --- /dev/null +++ b/benchmark/vm_not.yml @@ -0,0 +1,6 @@ +prelude: | + obj = Object.new +benchmark: + vm_not: | + !obj +loop_count: 30000000 diff --git a/benchmark/vm_poly_method.yml b/benchmark/vm_poly_method.yml new file mode 100644 index 0000000000..dd2f4e71de --- /dev/null +++ b/benchmark/vm_poly_method.yml @@ -0,0 +1,24 @@ +# loop_count is not utilized since `i` is involved in the script +benchmark: + vm_poly_method: | + class C1 + def m + 1 + end + end + class C2 + def m + 2 + end + end + + o1 = C1.new + o2 = C2.new + + i = 0 + while i<6_000_000 + o = (i % 2 == 0) ? o1 : o2 + o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m + i += 1 + end +loop_count: 1 diff --git a/benchmark/vm_poly_method_ov.yml b/benchmark/vm_poly_method_ov.yml new file mode 100644 index 0000000000..bca1b62729 --- /dev/null +++ b/benchmark/vm_poly_method_ov.yml @@ -0,0 +1,24 @@ +# loop_count is not utilized since `i` is involved in the script +benchmark: + vm_poly_method_ov: | + class C1 + def m + 1 + end + end + class C2 + def m + 2 + end + end + + o1 = C1.new + o2 = C2.new + + i = 0 + while i<6_000_000 + o = (i % 2 == 0) ? o1 : o2 + # o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m + i += 1 + end +loop_count: 1 diff --git a/benchmark/vm_poly_same_method.yml b/benchmark/vm_poly_same_method.yml new file mode 100644 index 0000000000..6c5404ac84 --- /dev/null +++ b/benchmark/vm_poly_same_method.yml @@ -0,0 +1,25 @@ +prelude: | + module AR; end + class AR::Base + def create_or_update + nil + end + def save + create_or_update + end + end + class Foo < AR::Base; end + class Bar < AR::Base; end + o1 = Foo.new + o2 = Bar.new +benchmark: + vm_poly_same_method: | + o1.save; o2.save; + o1.save; o2.save; + o1.save; o2.save; + o1.save; o2.save; + o1.save; o2.save; + o1.save; o2.save; + o1.save; o2.save; + o1.save; o2.save; +loop_count: 6000000 diff --git a/benchmark/vm_poly_singleton.yml b/benchmark/vm_poly_singleton.yml new file mode 100644 index 0000000000..c7923160fb --- /dev/null +++ b/benchmark/vm_poly_singleton.yml @@ -0,0 +1,18 @@ +# loop_count is not utilized since `i` is involved in the script +benchmark: + vm_poly_singleton: | + class C1 + def m; 1; end + end + + o1 = C1.new + o2 = C1.new + o2.singleton_class + + i = 0 + while i<6_000_000 # benchmark loop 2 + o = (i % 2 == 0) ? o1 : o2 + o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m + i += 1 + end +loop_count: 1 diff --git a/benchmark/vm_proc.yml b/benchmark/vm_proc.yml new file mode 100644 index 0000000000..2f8de6c272 --- /dev/null +++ b/benchmark/vm_proc.yml @@ -0,0 +1,12 @@ +prelude: | + def m &b + b + end + + pr = m{ + a = 1 + } +benchmark: + vm_proc: | + pr.call +loop_count: 6000000 diff --git a/benchmark/vm_raise1.yml b/benchmark/vm_raise1.yml new file mode 100644 index 0000000000..247d9f70ee --- /dev/null +++ b/benchmark/vm_raise1.yml @@ -0,0 +1,16 @@ +prelude: | + def rec n + if n > 0 + rec n-1 + else + raise + end + end +benchmark: + vm_raise1: | + begin + rec 1 + rescue + # ignore + end +loop_count: 6000000 diff --git a/benchmark/vm_raise2.yml b/benchmark/vm_raise2.yml new file mode 100644 index 0000000000..f0fa047b3c --- /dev/null +++ b/benchmark/vm_raise2.yml @@ -0,0 +1,16 @@ +prelude: | + def rec n + if n > 0 + rec n-1 + else + raise + end + end +benchmark: + vm_raise2: | + begin + rec 10 + rescue + # ignore + end +loop_count: 6000000 diff --git a/benchmark/vm_regexp.yml b/benchmark/vm_regexp.yml new file mode 100644 index 0000000000..2aa3d94dbd --- /dev/null +++ b/benchmark/vm_regexp.yml @@ -0,0 +1,8 @@ +prelude: | + str = 'xxxhogexxx' +benchmark: + vm_regexp: | + /hoge/ =~ str + vm_regexp_invert: | + str =~ /hoge/ +loop_count: 6000000 diff --git a/benchmark/vm_rescue.yml b/benchmark/vm_rescue.yml new file mode 100644 index 0000000000..b4a0af521f --- /dev/null +++ b/benchmark/vm_rescue.yml @@ -0,0 +1,6 @@ +benchmark: + vm_rescue: | + begin + rescue + end +loop_count: 30000000 diff --git a/benchmark/vm_send.yml b/benchmark/vm_send.yml new file mode 100644 index 0000000000..f31bc7ac89 --- /dev/null +++ b/benchmark/vm_send.yml @@ -0,0 +1,14 @@ +prelude: | + class C + def m + end + end + + o = C.new + m = :m +benchmark: + vm_send: | + o.__send__ :m + vm_send_var: | + o.__send__ m +loop_count: 6000000 diff --git a/benchmark/vm_send_cfunc.yml b/benchmark/vm_send_cfunc.yml new file mode 100644 index 0000000000..6f12b65176 --- /dev/null +++ b/benchmark/vm_send_cfunc.yml @@ -0,0 +1,14 @@ +prelude: | + ary = [] + kw = {a: 1} + empty_kw = {} + kw_ary = [Hash.ruby2_keywords_hash(a: 1)] + empty_kw_ary = [Hash.ruby2_keywords_hash({})] +benchmark: + vm_send_cfunc: itself + vm_send_cfunc_splat: itself(*ary) + vm_send_cfunc_splat_kw_hash: equal?(*kw_ary) + vm_send_cfunc_splat_empty_kw_hash: itself(*empty_kw_ary) + vm_send_cfunc_splat_kw: equal?(*ary, **kw) + vm_send_cfunc_splat_empty_kw: itself(*ary, **empty_kw) +loop_count: 20000000 diff --git a/benchmark/vm_simplereturn.yml b/benchmark/vm_simplereturn.yml new file mode 100644 index 0000000000..c9829cff0b --- /dev/null +++ b/benchmark/vm_simplereturn.yml @@ -0,0 +1,7 @@ +prelude: | + def m + return 1 + end +benchmark: + vm_simplereturn: m +loop_count: 30000000 diff --git a/benchmark/vm_string_literal.yml b/benchmark/vm_string_literal.yml new file mode 100644 index 0000000000..64439c7980 --- /dev/null +++ b/benchmark/vm_string_literal.yml @@ -0,0 +1,4 @@ +benchmark: + vm_string_literal: | + x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +loop_count: 6000000 diff --git a/benchmark/vm_struct_big_aref_hi.yml b/benchmark/vm_struct_big_aref_hi.yml new file mode 100644 index 0000000000..4cf78970cb --- /dev/null +++ b/benchmark/vm_struct_big_aref_hi.yml @@ -0,0 +1,7 @@ +prelude: | + s = Struct.new(*('a'..'z').map { |x| x.to_sym }) + x = s.new +benchmark: + vm_struct_big_aref_hi: | + x.z # x[25] +loop_count: 6000000 diff --git a/benchmark/vm_struct_big_aref_lo.yml b/benchmark/vm_struct_big_aref_lo.yml new file mode 100644 index 0000000000..c91af27fa5 --- /dev/null +++ b/benchmark/vm_struct_big_aref_lo.yml @@ -0,0 +1,7 @@ +prelude: | + s = Struct.new(*('a'..'z').map { |x| x.to_sym }) + x = s.new +benchmark: + vm_struct_big_aref_lo: | + x.k # x[10] +loop_count: 6000000 diff --git a/benchmark/vm_struct_big_aset.yml b/benchmark/vm_struct_big_aset.yml new file mode 100644 index 0000000000..69550d14ea --- /dev/null +++ b/benchmark/vm_struct_big_aset.yml @@ -0,0 +1,11 @@ +# loop_count is not utilized since `i` is involved in the script +benchmark: + vm_struct_big_aset: | + s = Struct.new(*('a'..'z').map { |x| x.to_sym }) + x = s.new + i = 0 + while i<6_000_000 + i += 1 + x.k = i # x[10] = i + end +loop_count: 1 diff --git a/benchmark/vm_struct_big_href_hi.yml b/benchmark/vm_struct_big_href_hi.yml new file mode 100644 index 0000000000..09b764dd13 --- /dev/null +++ b/benchmark/vm_struct_big_href_hi.yml @@ -0,0 +1,7 @@ +prelude: | + s = Struct.new(*('a'..'z').map { |x| x.to_sym }) + x = s.new +benchmark: + vm_struct_big_href_hi: | + x[:z] +loop_count: 6000000 diff --git a/benchmark/vm_struct_big_href_lo.yml b/benchmark/vm_struct_big_href_lo.yml new file mode 100644 index 0000000000..d2f00b220f --- /dev/null +++ b/benchmark/vm_struct_big_href_lo.yml @@ -0,0 +1,7 @@ +prelude: | + s = Struct.new(*('a'..'z').map { |x| x.to_sym }) + x = s.new +benchmark: + vm_struct_big_href_lo: | + x[:k] +loop_count: 6000000 diff --git a/benchmark/vm_struct_big_hset.yml b/benchmark/vm_struct_big_hset.yml new file mode 100644 index 0000000000..fc45cbee9c --- /dev/null +++ b/benchmark/vm_struct_big_hset.yml @@ -0,0 +1,11 @@ +# loop_count is not utilized since `i` is involved in the script +benchmark: + vm_struct_big_hset: | + s = Struct.new(*('a'..'z').map { |x| x.to_sym }) + x = s.new + i = 0 + while i<6_000_000 + i += 1 + x[:k] = i + end +loop_count: 1 diff --git a/benchmark/vm_struct_small_aref.yml b/benchmark/vm_struct_small_aref.yml new file mode 100644 index 0000000000..5a83251d1e --- /dev/null +++ b/benchmark/vm_struct_small_aref.yml @@ -0,0 +1,7 @@ +prelude: | + s = Struct.new(:a, :b, :c) + x = s.new +benchmark: + vm_struct_small_aref: | + x.a +loop_count: 6000000 diff --git a/benchmark/vm_struct_small_aset.yml b/benchmark/vm_struct_small_aset.yml new file mode 100644 index 0000000000..74f435f126 --- /dev/null +++ b/benchmark/vm_struct_small_aset.yml @@ -0,0 +1,11 @@ +# loop_count is not utilized since `i` is involved in the script +benchmark: + vm_struct_small_aset: | + s = Struct.new(:a, :b, :c) + x = s.new + i = 0 + while i<6_000_000 + i += 1 + x.a = i + end +loop_count: 1 diff --git a/benchmark/vm_struct_small_href.yml b/benchmark/vm_struct_small_href.yml new file mode 100644 index 0000000000..6b7d7f39e7 --- /dev/null +++ b/benchmark/vm_struct_small_href.yml @@ -0,0 +1,7 @@ +prelude: | + s = Struct.new(:a, :b, :c) + x = s.new +benchmark: + vm_struct_small_href: | + x[:a] +loop_count: 6000000 diff --git a/benchmark/vm_struct_small_hset.yml b/benchmark/vm_struct_small_hset.yml new file mode 100644 index 0000000000..5d43b150de --- /dev/null +++ b/benchmark/vm_struct_small_hset.yml @@ -0,0 +1,7 @@ +prelude: | + s = Struct.new(:a, :b, :c) + x = s.new +benchmark: + vm_struct_small_hset: | + x[:a] = 1 +loop_count: 6000000 diff --git a/benchmark/vm_super.yml b/benchmark/vm_super.yml new file mode 100644 index 0000000000..0d1e965c6e --- /dev/null +++ b/benchmark/vm_super.yml @@ -0,0 +1,17 @@ +prelude: | + class C + def m + 1 + end + end + + class CC < C + def m + super() + end + end + + obj = CC.new +benchmark: + vm_super: obj.m +loop_count: 6000000 diff --git a/benchmark/vm_super_splat_calls.yml b/benchmark/vm_super_splat_calls.yml new file mode 100644 index 0000000000..795e44e4da --- /dev/null +++ b/benchmark/vm_super_splat_calls.yml @@ -0,0 +1,25 @@ +prelude: | + @a = [1].freeze + @ea = [].freeze + @kw = {y: 1}.freeze + @b = lambda{} + extend(Module.new{def arg_splat(x=0, y: 0) end}) + extend(Module.new{def arg_splat_block(x=0, y: 0) end}) + extend(Module.new{def splat_kw_splat(x=0, y: 0) end}) + extend(Module.new{def splat_kw_splat_block(x=0, y: 0) end}) + extend(Module.new{def splat_kw(x=0, y: 0) end}) + extend(Module.new{def splat_kw_block(x=0, y: 0) end}) + + extend(Module.new{def arg_splat; super(1, *@ea) end}) + extend(Module.new{def arg_splat_block; super(1, *@ea, &@b) end}) + extend(Module.new{def splat_kw_splat; super(*@a, **@kw) end}) + extend(Module.new{def splat_kw_splat_block; super(*@a, **@kw, &@b) end}) + extend(Module.new{def splat_kw; super(*@a, y: 1) end}) + extend(Module.new{def splat_kw_block; super(*@a, y: 1, &@b) end}) +benchmark: + arg_splat: "arg_splat" + arg_splat_block: "arg_splat_block" + splat_kw_splat: "splat_kw_splat" + splat_kw_splat_block: "splat_kw_splat_block" + splat_kw: "splat_kw" + splat_kw_block: "splat_kw_block" diff --git a/benchmark/vm_swap.yml b/benchmark/vm_swap.yml new file mode 100644 index 0000000000..e824a65e0a --- /dev/null +++ b/benchmark/vm_swap.yml @@ -0,0 +1,7 @@ +prelude: | + a = 1 + b = 2 +benchmark: + vm_swap: | + a, b = b, a +loop_count: 30000000 diff --git a/benchmark/vm_symbol_block_pass.rb b/benchmark/vm_symbol_block_pass.rb new file mode 100644 index 0000000000..1d433353e1 --- /dev/null +++ b/benchmark/vm_symbol_block_pass.rb @@ -0,0 +1,13 @@ +class C + 1000.times {|i| + eval("def i#{i};end") + } +end + +c = C.new +m = C.instance_methods(false) +5_000.times do + m.each do |n| + c.tap(&n) + end +end diff --git a/benchmark/vm_thread_alive_check.yml b/benchmark/vm_thread_alive_check.yml new file mode 100644 index 0000000000..d21737d3e8 --- /dev/null +++ b/benchmark/vm_thread_alive_check.yml @@ -0,0 +1,8 @@ +benchmark: + vm_thread_alive_check: | + t = Thread.new{} + while t.alive? + Thread.pass + end +loop_count: 50_000 + diff --git a/benchmark/bm_vm_thread_close.rb b/benchmark/vm_thread_close.rb index 3e9a265ce8..3e9a265ce8 100644 --- a/benchmark/bm_vm_thread_close.rb +++ b/benchmark/vm_thread_close.rb diff --git a/benchmark/vm_thread_condvar1.rb b/benchmark/vm_thread_condvar1.rb new file mode 100644 index 0000000000..feed27c3ad --- /dev/null +++ b/benchmark/vm_thread_condvar1.rb @@ -0,0 +1,28 @@ +# two threads, two mutex, two condvar ping-pong +require 'thread' +m1 = Thread::Mutex.new +m2 = Thread::Mutex.new +cv1 = Thread::ConditionVariable.new +cv2 = Thread::ConditionVariable.new +max = 100000 +i = 0 +wait = nil +m2.synchronize do + wait = Thread.new do + m1.synchronize do + m2.synchronize { cv2.signal } + while (i += 1) < max + cv1.wait(m1) + cv2.signal + end + end + end + cv2.wait(m2) +end +m1.synchronize do + while i < max + cv1.signal + cv2.wait(m1) + end +end +wait.join diff --git a/benchmark/vm_thread_condvar2.rb b/benchmark/vm_thread_condvar2.rb new file mode 100644 index 0000000000..6590c4134b --- /dev/null +++ b/benchmark/vm_thread_condvar2.rb @@ -0,0 +1,35 @@ +# many threads, one mutex, many condvars +require 'thread' +m = Thread::Mutex.new +cv1 = Thread::ConditionVariable.new +cv2 = Thread::ConditionVariable.new +max = 1000 +n = 100 +waiting = 0 +scvs = [] +waiters = n.times.map do |i| + start_cv = Thread::ConditionVariable.new + scvs << start_cv + start_mtx = Thread::Mutex.new + start_mtx.synchronize do + th = Thread.new(start_mtx, start_cv) do |sm, scv| + m.synchronize do + sm.synchronize { scv.signal } + max.times do + cv2.signal if (waiting += 1) == n + cv1.wait(m) + end + end + end + start_cv.wait(start_mtx) + th + end +end +m.synchronize do + max.times do + cv2.wait(m) until waiting == n + waiting = 0 + cv1.broadcast + end +end +waiters.each(&:join) diff --git a/benchmark/bm_vm_thread_create_join.rb b/benchmark/vm_thread_create_join.rb index 393cd45df9..393cd45df9 100644 --- a/benchmark/bm_vm_thread_create_join.rb +++ b/benchmark/vm_thread_create_join.rb diff --git a/benchmark/bm_vm_thread_mutex1.rb b/benchmark/vm_thread_mutex1.rb index 5c9f85dfb7..66e42c85e1 100644 --- a/benchmark/bm_vm_thread_mutex1.rb +++ b/benchmark/vm_thread_mutex1.rb @@ -1,7 +1,7 @@ # one thread, one mutex (no contention) require 'thread' -m = Mutex.new +m = Thread::Mutex.new r = 0 max = 2000 lmax = max * max diff --git a/benchmark/bm_vm_thread_mutex2.rb b/benchmark/vm_thread_mutex2.rb index 10de59054f..6e6c804c31 100644 --- a/benchmark/bm_vm_thread_mutex2.rb +++ b/benchmark/vm_thread_mutex2.rb @@ -1,7 +1,7 @@ # two threads, one mutex require 'thread' -m = Mutex.new +m = Thread::Mutex.new r = 0 max = 2000 lmax = (max * max)/2 diff --git a/benchmark/bm_vm_thread_mutex3.rb b/benchmark/vm_thread_mutex3.rb index 7f9a44b39d..c750dc542a 100644 --- a/benchmark/bm_vm_thread_mutex3.rb +++ b/benchmark/vm_thread_mutex3.rb @@ -1,7 +1,7 @@ # 1000 threads, one mutex require 'thread' -m = Mutex.new +m = Thread::Mutex.new r = 0 max = 2000 (1..max).map{ diff --git a/benchmark/bm_vm_thread_pass.rb b/benchmark/vm_thread_pass.rb index b5b3c0bc85..438bd08d45 100644 --- a/benchmark/bm_vm_thread_pass.rb +++ b/benchmark/vm_thread_pass.rb @@ -1,8 +1,8 @@ -# Plenty Thtread.pass +# Plenty Thread.pass # A performance may depend on GVL implementation. -tmax = (ARGV.shift || 2).to_i -lmax = 200_000 / tmax +tmax = (ARGV.shift || 8).to_i +lmax = 400_000 / tmax (1..tmax).map{ Thread.new{ diff --git a/benchmark/vm_thread_pass_flood.rb b/benchmark/vm_thread_pass_flood.rb new file mode 100644 index 0000000000..65df8e6154 --- /dev/null +++ b/benchmark/vm_thread_pass_flood.rb @@ -0,0 +1,10 @@ +# n.b. this is a good test for GVL when pinned to a single CPU + +5_000.times{ + Thread.new{loop{Thread.pass}} +} + +i = 0 +while i<10_000 + i += 1 +end diff --git a/benchmark/bm_vm_thread_pipe.rb b/benchmark/vm_thread_pipe.rb index 272d231eba..112a621905 100644 --- a/benchmark/bm_vm_thread_pipe.rb +++ b/benchmark/vm_thread_pipe.rb @@ -1,4 +1,4 @@ -# Mesure small and plenty pipe read/write. +# Measure small and plenty pipe read/write. # A performance may depend on GVL implementation. lmax = 100_000 diff --git a/benchmark/bm_vm_thread_queue.rb b/benchmark/vm_thread_queue.rb index 37381ae62b..1dd3696a3c 100644 --- a/benchmark/bm_vm_thread_queue.rb +++ b/benchmark/vm_thread_queue.rb @@ -1,7 +1,7 @@ require 'thread' -n = 1_000_000 -q = Queue.new +n = 10_000_000 +q = Thread::Queue.new consumer = Thread.new{ while q.pop # consuming diff --git a/benchmark/vm_thread_sized_queue.rb b/benchmark/vm_thread_sized_queue.rb new file mode 100644 index 0000000000..7b9af5482b --- /dev/null +++ b/benchmark/vm_thread_sized_queue.rb @@ -0,0 +1,20 @@ +require 'thread' +# on producer, one consumer + +n = 1_000_000 +q = Thread::SizedQueue.new(100) +consumer = Thread.new{ + while q.pop + # consuming + end +} + +producer = Thread.new{ + while n > 0 + q.push true + n -= 1 + end + q.push nil +} + +consumer.join diff --git a/benchmark/vm_thread_sized_queue2.rb b/benchmark/vm_thread_sized_queue2.rb new file mode 100644 index 0000000000..de9f55e978 --- /dev/null +++ b/benchmark/vm_thread_sized_queue2.rb @@ -0,0 +1,23 @@ +require 'thread' +# one producer, many consumers +n = 1_000_000 +m = 10 +q = Thread::SizedQueue.new(100) +consumers = m.times.map do + Thread.new do + while q.pop + # consuming + end + end +end + +producer = Thread.new do + while n > 0 + q.push true + n -= 1 + end + m.times { q.push nil } +end + +producer.join +consumers.each(&:join) diff --git a/benchmark/vm_thread_sized_queue3.rb b/benchmark/vm_thread_sized_queue3.rb new file mode 100644 index 0000000000..ce5f1796d8 --- /dev/null +++ b/benchmark/vm_thread_sized_queue3.rb @@ -0,0 +1,22 @@ +require 'thread' +# many producers, one consumer +n = 1_000_000 +m = 10 +q = Thread::SizedQueue.new(100) +consumer = Thread.new do + while q.pop + # consuming + end +end + +producers = m.times.map do + Thread.new do + while n > 0 + q.push true + n -= 1 + end + end +end +producers.each(&:join) +q.push nil +consumer.join diff --git a/benchmark/vm_thread_sized_queue4.rb b/benchmark/vm_thread_sized_queue4.rb new file mode 100644 index 0000000000..a9b7d80ec0 --- /dev/null +++ b/benchmark/vm_thread_sized_queue4.rb @@ -0,0 +1,26 @@ +require 'thread' +# many producers, many consumers +nr = 1_000_000 +n = 10 +m = 10 +q = Thread::SizedQueue.new(100) +consumers = n.times.map do + Thread.new do + while q.pop + # consuming + end + end +end + +producers = m.times.map do + Thread.new do + while nr > 0 + q.push true + nr -= 1 + end + end +end + +producers.each(&:join) +n.times { q.push nil } +consumers.each(&:join) diff --git a/benchmark/vm_thread_sleep.yml b/benchmark/vm_thread_sleep.yml new file mode 100644 index 0000000000..96901d8466 --- /dev/null +++ b/benchmark/vm_thread_sleep.yml @@ -0,0 +1,4 @@ +benchmark: + vm_thread_sleep: | + Thread.new { sleep } +loop_count: 10_000 diff --git a/benchmark/vm_unif1.yml b/benchmark/vm_unif1.yml new file mode 100644 index 0000000000..04187bb0e2 --- /dev/null +++ b/benchmark/vm_unif1.yml @@ -0,0 +1,7 @@ +prelude: | + def m a, b + end +benchmark: + vm_unif1: | + m 100, 200 +loop_count: 6000000 diff --git a/benchmark/vm_yield.yml b/benchmark/vm_yield.yml new file mode 100644 index 0000000000..230be3d84f --- /dev/null +++ b/benchmark/vm_yield.yml @@ -0,0 +1,13 @@ +# while loop cost is not removed due to benchmark_driver.gem's limitation +benchmark: + vm_yield: | + def m + i = 0 + while i<30_000_000 + i += 1 + yield + end + end + + m{} +loop_count: 1 diff --git a/benchmark/vm_zsuper.yml b/benchmark/vm_zsuper.yml new file mode 100644 index 0000000000..bfb5837578 --- /dev/null +++ b/benchmark/vm_zsuper.yml @@ -0,0 +1,18 @@ +prelude: | + class C + def m a + 1 + end + end + + class CC < C + def m a + super + end + end + + obj = CC.new +benchmark: + vm_zsuper: | + obj.m 10 +loop_count: 6000000 diff --git a/benchmark/vm_zsuper_splat_calls.yml b/benchmark/vm_zsuper_splat_calls.yml new file mode 100644 index 0000000000..82dc22349d --- /dev/null +++ b/benchmark/vm_zsuper_splat_calls.yml @@ -0,0 +1,28 @@ +prelude: | + a = [1].freeze + ea = [].freeze + kw = {y: 1}.freeze + b = lambda{} + extend(Module.new{def arg_splat(x=0, y: 0) end}) + extend(Module.new{def arg_splat_block(x=0, y: 0) end}) + extend(Module.new{def arg_splat_post(x=0, y: 0) end}) + extend(Module.new{def splat_kw_splat(x=0, y: 0) end}) + extend(Module.new{def splat_kw_splat_block(x=0, y: 0) end}) + extend(Module.new{def splat_kw(x=0, y: 0) end}) + extend(Module.new{def splat_kw_block(x=0, y: 0) end}) + + extend(Module.new{def arg_splat(x, *a) super end}) + extend(Module.new{def arg_splat_block(x, *a, &b) super end}) + extend(Module.new{def arg_splat_post(*a, x) super end}) + extend(Module.new{def splat_kw_splat(*a, **kw) super end}) + extend(Module.new{def splat_kw_splat_block(*a, **kw, &b) super end}) + extend(Module.new{def splat_kw(*a, y: 1) super end}) + extend(Module.new{def splat_kw_block(*a, y: 1, &b) super end}) +benchmark: + arg_splat: "arg_splat(1, *ea)" + arg_splat_block: "arg_splat_block(1, *ea, &b)" + arg_splat_post: "arg_splat_post(1, *ea, &b)" + splat_kw_splat: "splat_kw_splat(*a, **kw)" + splat_kw_splat_block: "splat_kw_splat_block(*a, **kw, &b)" + splat_kw: "splat_kw(*a, y: 1)" + splat_kw_block: "splat_kw_block(*a, y: 1, &b)" |
