diff options
Diffstat (limited to 'benchmark')
384 files changed, 4071 insertions, 1525 deletions
diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 0000000000..c222164be3 --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,72 @@ +# 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 +Usage: benchmark-driver [options] RUBY|YAML... + -r, --runner TYPE Specify runner type: ips, time, memory, once (default: ips) + -o, --output TYPE Specify output type: compare, simple, markdown, record (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) + --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) + -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 ffab116fcd..16296af12b 100644 --- a/benchmark/bm_app_aobench.rb +++ b/benchmark/app_aobench.rb @@ -1,3 +1,5 @@ +# coding: US-ASCII + # AO render benchmark # Original program (C) Syoyo Fujita in Javascript (and other languages) # https://code.google.com/p/aobench/ @@ -9,6 +11,8 @@ IMAGE_HEIGHT = 256 NSUBSAMPLES = 2 NAO_SAMPLES = 8 +srand(0) + class Vec def initialize(x, y, z) @x = x @@ -229,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| @@ -278,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..34a7b2e725 100644 --- a/benchmark/bm_app_fib.rb +++ b/benchmark/app_fib.rb diff --git a/benchmark/bm_app_lc_fizzbuzz.rb b/benchmark/app_lc_fizzbuzz.rb index f09574bbeb..f09574bbeb 100644 --- a/benchmark/bm_app_lc_fizzbuzz.rb +++ b/benchmark/app_lc_fizzbuzz.rb 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_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_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_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_regexp.rb b/benchmark/bm_vm2_regexp.rb deleted file mode 100644 index 55f9e957a3..0000000000 --- a/benchmark/bm_vm2_regexp.rb +++ /dev/null @@ -1,6 +0,0 @@ -i = 0 -str = 'xxxhogexxx' -while i<6_000_000 # benchmark loop 2 - /hoge/ =~ str - i += 1 -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_struct_big_aref_hi.rb b/benchmark/bm_vm2_struct_big_aref_hi.rb deleted file mode 100644 index 22cb26b0a5..0000000000 --- a/benchmark/bm_vm2_struct_big_aref_hi.rb +++ /dev/null @@ -1,7 +0,0 @@ -s = Struct.new(*('a'..'z').map { |x| x.to_sym }) -x = s.new -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - x.z # x[25] -end diff --git a/benchmark/bm_vm2_struct_big_aref_lo.rb b/benchmark/bm_vm2_struct_big_aref_lo.rb deleted file mode 100644 index 5e61a7087e..0000000000 --- a/benchmark/bm_vm2_struct_big_aref_lo.rb +++ /dev/null @@ -1,7 +0,0 @@ -s = Struct.new(*('a'..'z').map { |x| x.to_sym }) -x = s.new -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - x.k # x[10] -end diff --git a/benchmark/bm_vm2_struct_big_aset.rb b/benchmark/bm_vm2_struct_big_aset.rb deleted file mode 100644 index 5a1c3d16f3..0000000000 --- a/benchmark/bm_vm2_struct_big_aset.rb +++ /dev/null @@ -1,7 +0,0 @@ -s = Struct.new(*('a'..'z').map { |x| x.to_sym }) -x = s.new -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - x.k = i # x[10] = i -end diff --git a/benchmark/bm_vm2_struct_small_aref.rb b/benchmark/bm_vm2_struct_small_aref.rb deleted file mode 100644 index 8eaa555b41..0000000000 --- a/benchmark/bm_vm2_struct_small_aref.rb +++ /dev/null @@ -1,7 +0,0 @@ -s = Struct.new(:a, :b, :c) -x = s.new -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - x.a -end diff --git a/benchmark/bm_vm2_struct_small_aset.rb b/benchmark/bm_vm2_struct_small_aset.rb deleted file mode 100644 index ecd0f95669..0000000000 --- a/benchmark/bm_vm2_struct_small_aset.rb +++ /dev/null @@ -1,7 +0,0 @@ -s = Struct.new(:a, :b, :c) -x = s.new -i = 0 -while i<6_000_000 # benchmark loop 2 - i += 1 - x.a = i -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_get.yml b/benchmark/buffer_get.yml new file mode 100644 index 0000000000..e375dcf85d --- /dev/null +++ b/benchmark/buffer_get.yml @@ -0,0 +1,9 @@ +benchmark: + - name: buffer.get + prelude: buffer = IO::Buffer.new(32, IO::Buffer::MAPPED) + script: buffer.get(:U32, 0) + loop_count: 20000000 + - name: string.unpack + prelude: string = "\0" * 32 + script: string.unpack("C") + loop_count: 20000000 diff --git a/benchmark/cgi_escape_html.yml b/benchmark/cgi_escape_html.yml new file mode 100644 index 0000000000..af6abd08ac --- /dev/null +++ b/benchmark/cgi_escape_html.yml @@ -0,0 +1,40 @@ +prelude: require 'cgi/escape' +benchmark: + - name: escape_html_blank + prelude: str = "" + script: CGI.escapeHTML(str) + loop_count: 20000000 + - name: escape_html_short_none + prelude: str = "abcde" + script: CGI.escapeHTML(str) + loop_count: 20000000 + - name: escape_html_short_one + prelude: str = "abcd<" + script: CGI.escapeHTML(str) + loop_count: 20000000 + - name: escape_html_short_all + prelude: str = "'&\"<>" + script: CGI.escapeHTML(str) + loop_count: 5000000 + - name: escape_html_long_none + prelude: str = "abcde" * 300 + script: CGI.escapeHTML(str) + loop_count: 1000000 + - name: escape_html_long_all + prelude: str = "'&\"<>" * 10 + script: CGI.escapeHTML(str) + loop_count: 1000000 + - name: escape_html_real + prelude: | # http://example.com/ + str = <<~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(str) + loop_count: 1000000 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/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_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_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_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_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/bm_hash_aref_flo.rb b/benchmark/hash_aref_flo.rb index 2217274c82..2217274c82 100644 --- a/benchmark/bm_hash_aref_flo.rb +++ b/benchmark/hash_aref_flo.rb 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/bm_hash_aref_sym.rb b/benchmark/hash_aref_sym.rb index f75d163fe6..f75d163fe6 100644 --- a/benchmark/bm_hash_aref_sym.rb +++ b/benchmark/hash_aref_sym.rb diff --git a/benchmark/bm_hash_aref_sym_long.rb b/benchmark/hash_aref_sym_long.rb index 9dab8df7be..9dab8df7be 100644 --- a/benchmark/bm_hash_aref_sym_long.rb +++ b/benchmark/hash_aref_sym_long.rb 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/bm_hash_ident_flo.rb b/benchmark/hash_ident_flo.rb index 0c7edfed3e..0c7edfed3e 100644 --- a/benchmark/bm_hash_ident_flo.rb +++ b/benchmark/hash_ident_flo.rb 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/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/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_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/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/mjit.rb b/benchmark/lib/benchmark_driver/runner/mjit.rb new file mode 100644 index 0000000000..1d4693e8be --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/mjit.rb @@ -0,0 +1,34 @@ +require 'benchmark_driver/struct' +require 'benchmark_driver/metric' +require 'erb' + +# A runner to measure after-JIT performance easily +class BenchmarkDriver::Runner::Mjit < BenchmarkDriver::Runner::Ips + # 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]).extend(Module.new{ + def parse(**) + jobs = super + jobs.map do |job| + job = job.dup + job.prelude = "#{job.prelude}\n#{<<~EOS}" + if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? + __bmdv_ruby_i = 0 + while __bmdv_ruby_i < 10000 # jit_min_calls + #{job.script} + __bmdv_ruby_i += 1 + end + RubyVM::MJIT.pause # compile + #{job.script} + RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile + #{job.script} + RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile 2 + end + EOS + job + end + end + }) +end diff --git a/benchmark/lib/benchmark_driver/runner/mjit_exec.rb b/benchmark/lib/benchmark_driver/runner/mjit_exec.rb new file mode 100644 index 0000000000..eac3dfba84 --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/mjit_exec.rb @@ -0,0 +1,237 @@ +require 'benchmark_driver/struct' +require 'benchmark_driver/metric' +require 'erb' + +# A special runner dedicated for measuring mjit_exec overhead. +class BenchmarkDriver::Runner::MjitExec + METRIC = BenchmarkDriver::Metric.new(name: 'Iteration per second', unit: 'i/s') + + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = ::BenchmarkDriver::Struct.new( + :name, # @param [String] name - This is mandatory for all runner + :metrics, # @param [Array<BenchmarkDriver::Metric>] + :num_methods, # @param [Integer] num_methods - The number of methods to be defined + :loop_count, # @param [Integer] loop_count + :from_jit, # @param [TrueClass,FalseClass] from_jit - Whether the mjit_exec() is from JIT or not + :to_jit, # @param [TrueClass,FalseClass] to_jit - Whether the mjit_exec() is to JIT or not + ) + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + class << JobParser = Module.new + # @param [Array,String] num_methods + # @param [Integer] loop_count + # @param [TrueClass,FalseClass] from_jit + # @param [TrueClass,FalseClass] to_jit + def parse(num_methods:, loop_count:, from_jit:, to_jit:) + if num_methods.is_a?(String) + num_methods = eval(num_methods) + end + + num_methods.map do |num| + if num_methods.size > 1 + suffix = "[#{'%4d' % num}]" + else + suffix = "_#{num}" + end + Job.new( + name: "mjit_exec_#{from_jit ? 'JT' : 'VM'}2#{to_jit ? 'JT' : 'VM'}#{suffix}", + metrics: [METRIC], + num_methods: num, + loop_count: loop_count, + from_jit: from_jit, + to_jit: to_jit, + ) + end + end + end + + # @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) + @output.with_benchmark do + jobs.each do |job| + @output.with_job(name: job.name) do + @contexts.each do |context| + result = BenchmarkDriver::Repeater.with_repeat(config: @config, larger_better: true, rest_on_average: :average) do + run_benchmark(job, context: context) + end + value, duration = result.value + @output.with_context(name: context.name, executable: context.executable, gems: context.gems, prelude: context.prelude) do + @output.report(values: { METRIC => value }, 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:) + if job.from_jit + if job.to_jit + benchmark = BenchmarkJT2JT.new(num_methods: job.num_methods, loop_count: job.loop_count) + else + raise NotImplementedError, "JT2VM is not implemented yet" + end + else + if job.to_jit + benchmark = BenchmarkVM2JT.new(num_methods: job.num_methods, loop_count: job.loop_count) + else + benchmark = BenchmarkVM2VM.new(num_methods: job.num_methods, loop_count: job.loop_count) + end + end + + duration = Tempfile.open(['benchmark_driver-result', '.txt']) do |f| + with_script(benchmark.render(result: f.path)) do |path| + opt = [] + if context.executable.command.any? { |c| c.start_with?('--jit') } + opt << '--jit-min-calls=2' + end + IO.popen([*context.executable.command, '--disable-gems', *opt, path], &:read) + if $?.success? + Float(f.read) + else + BenchmarkDriver::Result::ERROR + end + end + end + + [job.loop_count.to_f / duration, duration] + 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 [Integer] num_methods + # @param [Integer] loop_count + BenchmarkVM2VM = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do + # @param [String] result - A file to write result + def render(result:) + ERB.new(<<~EOS, trim_mode: '%').result(binding) + % num_methods.times do |i| + def a<%= i %> + nil + end + % end + RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? + + def vm + t = Process.clock_gettime(Process::CLOCK_MONOTONIC) + i = 0 + while i < <%= loop_count / 1000 %> + % 1000.times do |i| + a<%= i % num_methods %> + % end + i += 1 + end + % (loop_count % 1000).times do |i| + a<%= i % num_methods %> + % end + Process.clock_gettime(Process::CLOCK_MONOTONIC) - t + end + + vm # warmup call cache + File.write(<%= result.dump %>, vm) + EOS + end + end + private_constant :BenchmarkVM2VM + + # @param [Integer] num_methods + # @param [Integer] loop_count + BenchmarkVM2JT = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do + # @param [String] result - A file to write result + def render(result:) + ERB.new(<<~EOS, trim_mode: '%').result(binding) + % num_methods.times do |i| + def a<%= i %> + nil + end + a<%= i %> + a<%= i %> # --jit-min-calls=2 + % end + RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? + + def vm + t = Process.clock_gettime(Process::CLOCK_MONOTONIC) + i = 0 + while i < <%= loop_count / 1000 %> + % 1000.times do |i| + a<%= i % num_methods %> + % end + i += 1 + end + % (loop_count % 1000).times do |i| + a<%= i % num_methods %> + % end + Process.clock_gettime(Process::CLOCK_MONOTONIC) - t + end + + vm # warmup call cache + File.write(<%= result.dump %>, vm) + EOS + end + end + private_constant :BenchmarkVM2JT + + # @param [Integer] num_methods + # @param [Integer] loop_count + BenchmarkJT2JT = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do + # @param [String] result - A file to write result + def render(result:) + ERB.new(<<~EOS, trim_mode: '%').result(binding) + % num_methods.times do |i| + def a<%= i %> + nil + end + % end + + # You may need to: + # * Increase `JIT_ISEQ_SIZE_THRESHOLD` to 10000000 in mjit.h + # * Always return false in `inlinable_iseq_p()` of mjit_compile.c + def jit + t = Process.clock_gettime(Process::CLOCK_MONOTONIC) + i = 0 + while i < <%= loop_count / 1000 %> + % 1000.times do |i| + a<%= i % num_methods %> + % end + i += 1 + end + % (loop_count % 1000).times do |i| + a<%= i % num_methods %> + % end + Process.clock_gettime(Process::CLOCK_MONOTONIC) - t + end + + jit + jit + RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? + File.write(<%= result.dump %>, jit) + EOS + end + end + private_constant :BenchmarkJT2JT +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..c730b8e4a5 --- /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!(&:take) + +<% 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/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..d3375c744c 100644 --- a/benchmark/bm_loop_generator.rb +++ b/benchmark/loop_generator.rb 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/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/bm_marshal_dump_flo.rb b/benchmark/marshal_dump_flo.rb index 9b8d0c6afb..9b8d0c6afb 100644 --- a/benchmark/bm_marshal_dump_flo.rb +++ b/benchmark/marshal_dump_flo.rb 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_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..4be9333e23 --- /dev/null +++ b/benchmark/masgn.yml @@ -0,0 +1,29 @@ +prelude: | + a = [nil] * 3 + b = Class.new{attr_writer :a, :b, :c}.new + c, d, e, f = nil, nil, nil, 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)" 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/mjit_exec_jt2jt.yml b/benchmark/mjit_exec_jt2jt.yml new file mode 100644 index 0000000000..6c303c7a44 --- /dev/null +++ b/benchmark/mjit_exec_jt2jt.yml @@ -0,0 +1,6 @@ +type: lib/benchmark_driver/runner/mjit_exec +num_methods: [1] +#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000] +loop_count: 50000000 +from_jit: true +to_jit: true diff --git a/benchmark/mjit_exec_vm2jt.yml b/benchmark/mjit_exec_vm2jt.yml new file mode 100644 index 0000000000..764883f070 --- /dev/null +++ b/benchmark/mjit_exec_vm2jt.yml @@ -0,0 +1,6 @@ +type: lib/benchmark_driver/runner/mjit_exec +num_methods: [1] +#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000] +loop_count: 50000000 +from_jit: false +to_jit: true diff --git a/benchmark/mjit_exec_vm2vm.yml b/benchmark/mjit_exec_vm2vm.yml new file mode 100644 index 0000000000..030aa76c1c --- /dev/null +++ b/benchmark/mjit_exec_vm2vm.yml @@ -0,0 +1,6 @@ +type: lib/benchmark_driver/runner/mjit_exec +num_methods: [1] +#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000] +loop_count: 50000000 +from_jit: false +to_jit: false diff --git a/benchmark/mjit_exivar.yml b/benchmark/mjit_exivar.yml new file mode 100644 index 0000000000..2584fa6410 --- /dev/null +++ b/benchmark/mjit_exivar.yml @@ -0,0 +1,18 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + class Bench < Hash + def initialize + @exivar = nil + end + + def exivar + @exivar + end + end + + bench = Bench.new + +benchmark: + mjit_exivar: bench.exivar + +loop_count: 200000000 diff --git a/benchmark/mjit_integer.yml b/benchmark/mjit_integer.yml new file mode 100644 index 0000000000..a6b5c9ee16 --- /dev/null +++ b/benchmark/mjit_integer.yml @@ -0,0 +1,32 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_abs(int) int.abs end + def mjit_bit_length(int) int.bit_length end + def mjit_comp(int) ~int end + def mjit_even?(int) int.even? end + def mjit_integer?(int) int.integer? end + def mjit_magnitude(int) int.magnitude end + def mjit_odd?(int) int.odd? end + def mjit_ord(int) int.ord end + def mjit_size(int) int.size end + def mjit_to_i(int) int.to_i end + def mjit_to_int(int) int.to_int end + def mjit_uminus(int) -int end + def mjit_zero?(int) int.zero? end + +benchmark: + - mjit_abs(-1) + - mjit_bit_length(100) + - mjit_comp(1) + - mjit_even?(2) + - mjit_integer?(0) + - mjit_magnitude(-1) + - mjit_odd?(1) + - mjit_ord(1) + - mjit_size(1) + - mjit_to_i(1) + - mjit_to_int(1) + - mjit_uminus(1) + - mjit_zero?(0) + +loop_count: 40000000 diff --git a/benchmark/mjit_kernel.yml b/benchmark/mjit_kernel.yml new file mode 100644 index 0000000000..7720e65c2c --- /dev/null +++ b/benchmark/mjit_kernel.yml @@ -0,0 +1,20 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_class(obj) + obj.class + end + + def mjit_frozen?(obj) + obj.frozen? + end + + str = "" + fstr = "".freeze + +benchmark: + - mjit_class(self) + - mjit_class(1) + - mjit_frozen?(str) + - mjit_frozen?(fstr) + +loop_count: 40000000 diff --git a/benchmark/mjit_leave.yml b/benchmark/mjit_leave.yml new file mode 100644 index 0000000000..9ac68b164b --- /dev/null +++ b/benchmark/mjit_leave.yml @@ -0,0 +1,8 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def leave + nil + end +benchmark: + mjit_leave: leave +loop_count: 200000000 diff --git a/benchmark/mjit_opt_cc_insns.yml b/benchmark/mjit_opt_cc_insns.yml new file mode 100644 index 0000000000..fed6d34bd5 --- /dev/null +++ b/benchmark/mjit_opt_cc_insns.yml @@ -0,0 +1,27 @@ +# opt_* insns using vm_method_cfunc_is with send-compatible operands: +# * opt_nil_p +# * opt_not +# * opt_eq +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_nil?(obj) + obj.nil? + end + + def mjit_not(obj) + !obj + end + + def mjit_eq(a, b) + a == b + end + +benchmark: + - script: mjit_nil?(1) + loop_count: 40000000 + - script: mjit_not(1) + loop_count: 40000000 + - script: mjit_eq(1, nil) + loop_count: 8000000 + - script: mjit_eq(nil, 1) + loop_count: 8000000 diff --git a/benchmark/mjit_struct_aref.yml b/benchmark/mjit_struct_aref.yml new file mode 100644 index 0000000000..bfba1323f2 --- /dev/null +++ b/benchmark/mjit_struct_aref.yml @@ -0,0 +1,10 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_struct_aref(struct) + struct.aa + end + struct = Struct.new(:a0, :a1, :a2, :a3, :a4, :a5, :a6, :a7, :a8, :a9, :aa).new + +benchmark: mjit_struct_aref(struct) + +loop_count: 40000000 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..fba67a5f6a --- /dev/null +++ b/benchmark/nilclass.yml @@ -0,0 +1,6 @@ +benchmark: + to_i: | + nil.to_i + to_f: | + nil.to_f +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..433c2268a3 --- /dev/null +++ b/benchmark/numeric_methods.yml @@ -0,0 +1,13 @@ +prelude: | + int = 42 + flo = 4.2 +benchmark: + real?: | + int.real? + integer?: | + flo.integer? + finite?: | + int.finite? + infinite?: | + int.infinite? +loop_count: 20000000 diff --git a/benchmark/object_allocate.yml b/benchmark/object_allocate.yml new file mode 100644 index 0000000000..93ff463e41 --- /dev/null +++ b/benchmark/object_allocate.yml @@ -0,0 +1,21 @@ +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 + # 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 +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/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/realpath.yml b/benchmark/realpath.yml new file mode 100644 index 0000000000..90a029d5b9 --- /dev/null +++ b/benchmark/realpath.yml @@ -0,0 +1,30 @@ +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' +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/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/bm_securerandom.rb b/benchmark/securerandom.rb index a082ea6d5b..a082ea6d5b 100644 --- a/benchmark/bm_securerandom.rb +++ b/benchmark/securerandom.rb 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..99683505f9 100644 --- a/benchmark/wc.input.base +++ b/benchmark/so_count_words.yml @@ -1,25 +1,65 @@ -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 + } + open(wcinput, 'w'){|f| f.write data} + end + 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 + 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}" + +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..8c136baa6c 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, @@ -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..d6c5bb9e61 100644 --- a/benchmark/bm_so_nbody.rb +++ b/benchmark/so_nbody.rb 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..2354040a04 --- /dev/null +++ b/benchmark/string_casecmp.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-1: lstr1.casecmp(ustr1) + casecmp-10: lstr10.casecmp(ustr10) + casecmp-100: lstr100.casecmp(ustr100) + casecmp-1000: lstr1000.casecmp(ustr1000) + casecmp-nonascii1: lnonascii1.casecmp(unonascii1) + casecmp-nonascii10: lnonascii10.casecmp(unonascii10) + casecmp-nonascii100: lnonascii100.casecmp(unonascii100) + casecmp-nonascii1000: lnonascii1000.casecmp(unonascii1000) 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_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_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_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/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_parse.yml b/benchmark/time_parse.yml new file mode 100644 index 0000000000..a6d6948b9c --- /dev/null +++ b/benchmark/time_parse.yml @@ -0,0 +1,8 @@ +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) 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/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_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..6064d4eed0 --- /dev/null +++ b/benchmark/vm_const.yml @@ -0,0 +1,7 @@ +prelude: | + Const = 1 +benchmark: + vm_const: | + j = Const + k = Const +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_newlambda.rb b/benchmark/vm_dstr_int.rb index 6422c9b0d0..ed380d7595 100644 --- a/benchmark/bm_vm2_newlambda.rb +++ b/benchmark/vm_dstr_int.rb @@ -1,5 +1,5 @@ i = 0 while i<6_000_000 # benchmark loop 2 i += 1 - lambda {} + 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_eval.rb b/benchmark/vm_dstr_sym.rb index 307cfc28ef..484b8f8150 100644 --- a/benchmark/bm_vm2_eval.rb +++ b/benchmark/vm_dstr_sym.rb @@ -1,6 +1,6 @@ i = 0 +x = y = :z while i<6_000_000 # benchmark loop 2 i += 1 - eval("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_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_init.yml b/benchmark/vm_ivar_init.yml new file mode 100644 index 0000000000..c6f1633907 --- /dev/null +++ b/benchmark/vm_ivar_init.yml @@ -0,0 +1,14 @@ +prelude: | + class C + def initialize + @a = nil + @b = nil + @c = nil + @d = nil + @e = nil + end + end +benchmark: + vm_ivar_init: | + C.new +loop_count: 30000000 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_subclass.yml b/benchmark/vm_ivar_set_subclass.yml new file mode 100644 index 0000000000..2653d36ded --- /dev/null +++ b/benchmark/vm_ivar_set_subclass.yml @@ -0,0 +1,17 @@ +prelude: | + class A + def initialize + @a = nil + @b = nil + @c = nil + @d = nil + @e = nil + end + end + class B < A; end + class C < A; end +benchmark: + vm_ivar_init_subclass: | + B.new + C.new +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_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_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..b114ac317d --- /dev/null +++ b/benchmark/vm_send_cfunc.yml @@ -0,0 +1,3 @@ +benchmark: + vm_send_cfunc: self.class +loop_count: 100000000 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_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 |
