diff options
Diffstat (limited to 'benchmark')
| -rw-r--r-- | benchmark/README.md | 2 | ||||
| -rw-r--r-- | benchmark/class_superclass.yml | 23 | ||||
| -rw-r--r-- | benchmark/file_basename.yml | 6 | ||||
| -rw-r--r-- | benchmark/file_dirname.yml | 6 | ||||
| -rw-r--r-- | benchmark/file_extname.yml | 6 | ||||
| -rw-r--r-- | benchmark/file_join.yml | 7 | ||||
| -rw-r--r-- | benchmark/io_close.yml | 13 | ||||
| -rw-r--r-- | benchmark/io_close_contended.yml | 21 | ||||
| -rw-r--r-- | benchmark/lib/benchmark_driver/runner/ractor.rb | 2 | ||||
| -rw-r--r-- | benchmark/module_eqq.yml | 7 | ||||
| -rw-r--r-- | benchmark/nilclass.yml | 6 | ||||
| -rw-r--r-- | benchmark/object_allocate.yml | 1 | ||||
| -rw-r--r-- | benchmark/object_class.yml | 40 | ||||
| -rw-r--r-- | benchmark/set.yml | 4 | ||||
| -rw-r--r-- | benchmark/string_casecmp.yml | 2 | ||||
| -rw-r--r-- | benchmark/struct_accessor.yml | 12 | ||||
| -rw-r--r-- | benchmark/time_now.yml | 1 | ||||
| -rw-r--r-- | benchmark/vm_ivar_get.yml | 67 | ||||
| -rw-r--r-- | benchmark/vm_ivar_set_on_instance.yml | 63 |
19 files changed, 278 insertions, 11 deletions
diff --git a/benchmark/README.md b/benchmark/README.md index c5c29d0daf..9f9192685e 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -40,7 +40,7 @@ Usage: benchmark-driver [options] RUBY|YAML... --filter REGEXP Filter out benchmarks with given regexp --run-duration SECONDS Warmup estimates loop_count to run for this duration (default: 3) --timeout SECONDS Timeout ruby command execution with timeout(1) - -v, --verbose Verbose mode. Multiple -v options increase visilibity (max: 2) + -v, --verbose Verbose mode. Multiple -v options increase visibility (max: 2) ``` ## make benchmark diff --git a/benchmark/class_superclass.yml b/benchmark/class_superclass.yml new file mode 100644 index 0000000000..847ff811f1 --- /dev/null +++ b/benchmark/class_superclass.yml @@ -0,0 +1,23 @@ +prelude: | + class SimpleClass; end + class OneModuleClass + 1.times { include Module.new } + end + class MediumClass + 10.times { include Module.new } + end + class LargeClass + 100.times { include Module.new } + end +benchmark: + object_class_superclass: | + Object.superclass + simple_class_superclass: | + SimpleClass.superclass + one_module_class: | + OneModuleClass.superclass + medium_class_superclass: | + MediumClass.superclass + large_class_superclass: | + LargeClass.superclass +loop_count: 20000000 diff --git a/benchmark/file_basename.yml b/benchmark/file_basename.yml new file mode 100644 index 0000000000..fbd78785aa --- /dev/null +++ b/benchmark/file_basename.yml @@ -0,0 +1,6 @@ +prelude: | + # frozen_string_literal: true +benchmark: + long: File.basename("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml") + long_name: File.basename("Users_george_src_github.com_ruby_ruby_benchmark_file_dirname.yml") + withext: File.basename("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml", ".yml") diff --git a/benchmark/file_dirname.yml b/benchmark/file_dirname.yml new file mode 100644 index 0000000000..43a81c9371 --- /dev/null +++ b/benchmark/file_dirname.yml @@ -0,0 +1,6 @@ +prelude: | + # frozen_string_literal: true +benchmark: + long: File.dirname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml") + short: File.dirname("foo/bar") + n_4: File.dirname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml", 4) diff --git a/benchmark/file_extname.yml b/benchmark/file_extname.yml new file mode 100644 index 0000000000..fb16e55840 --- /dev/null +++ b/benchmark/file_extname.yml @@ -0,0 +1,6 @@ +prelude: | + # frozen_string_literal: true +benchmark: + long: File.extname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml") + long_name: File.extname("Users_george_src_github.com_ruby_ruby_benchmark_file_dirname.yml") + short: File.extname("foo/bar") diff --git a/benchmark/file_join.yml b/benchmark/file_join.yml new file mode 100644 index 0000000000..845257cf1e --- /dev/null +++ b/benchmark/file_join.yml @@ -0,0 +1,7 @@ +prelude: | + # frozen_string_literal: true +benchmark: + two_strings: File.join(__FILE__, "path") + many_strings: File.join(__FILE__, "path", "a", "b", "c", "d") + array: File.join([__FILE__, "path", "a", "b", "c", "d"]) + mixed: File.join(__FILE__, "path", "a", "b", ["c", "d"]) diff --git a/benchmark/io_close.yml b/benchmark/io_close.yml new file mode 100644 index 0000000000..a552872884 --- /dev/null +++ b/benchmark/io_close.yml @@ -0,0 +1,13 @@ +prelude: | + ios = 1000.times.map do + 100.times.map{IO.pipe} + end +benchmark: + # Close IO + io_close: | + # Process each batch of ios per iteration of the benchmark. + ios.pop.each do |r, w| + r.close + w.close + end +loop_count: 100 diff --git a/benchmark/io_close_contended.yml b/benchmark/io_close_contended.yml new file mode 100644 index 0000000000..1d9e4e0d0f --- /dev/null +++ b/benchmark/io_close_contended.yml @@ -0,0 +1,21 @@ +prelude: | + ios = 100.times.map do + 10.times.map do + pipe = IO.pipe.tap do |r, w| + Thread.new do + r.read + rescue IOError + # Ignore + end + end + end + end +benchmark: + # Close IO + io_close_contended: | + # Process each batch of ios per iteration of the benchmark. + ios.pop.each do |r, w| + r.close + w.close + end +loop_count: 10 diff --git a/benchmark/lib/benchmark_driver/runner/ractor.rb b/benchmark/lib/benchmark_driver/runner/ractor.rb index c730b8e4a5..fd9c2dd4db 100644 --- a/benchmark/lib/benchmark_driver/runner/ractor.rb +++ b/benchmark/lib/benchmark_driver/runner/ractor.rb @@ -87,7 +87,7 @@ __bmdv_ractors << Ractor.new(__bmdv_loop_after - __bmdv_loop_before) { |__bmdv_l <% end %> # Wait for all Ractors before executing code to write results -__bmdv_ractors.map!(&:take) +__bmdv_ractors.map!(&:value) <% results.each do |result| %> File.write(<%= result.dump %>, __bmdv_ractors.shift) diff --git a/benchmark/module_eqq.yml b/benchmark/module_eqq.yml index a561fb86dc..2f9c490d92 100644 --- a/benchmark/module_eqq.yml +++ b/benchmark/module_eqq.yml @@ -1,4 +1,5 @@ prelude: | + module SomeModule; end class SimpleClass; end class MediumClass 10.times { include Module.new } @@ -24,4 +25,8 @@ benchmark: SimpleClass === LargeObj simple_class_eqq_huge_obj: | SimpleClass === HugeObj -loop_count: 20000000 + simple_class_eqq_module: | + SimpleClass === HugeObj + module_eqq_module: | + SomeModule === HugeObj +loop_count: 10000000 diff --git a/benchmark/nilclass.yml b/benchmark/nilclass.yml index da66e71068..66234c4cdf 100644 --- a/benchmark/nilclass.yml +++ b/benchmark/nilclass.yml @@ -1,10 +1,16 @@ prelude: | def a = nil benchmark: + rationalize: + nil.rationalize + to_c: | + nil.to_c to_i: | nil.to_i to_f: | nil.to_f + to_r: | + nil.to_r splat: | a(*nil) loop_count: 100000 diff --git a/benchmark/object_allocate.yml b/benchmark/object_allocate.yml index bdbd4536db..c6269923f0 100644 --- a/benchmark/object_allocate.yml +++ b/benchmark/object_allocate.yml @@ -45,4 +45,5 @@ benchmark: allocate_kwarg_params: "KWArg.new(a: 1, b: 2, c: 3, d: 4)" allocate_mixed_params: "Mixed.new(1, 2, c: 3, d: 4)" allocate_no_params: "Object.new" + allocate_allocate: "Object.allocate" loop_count: 100000 diff --git a/benchmark/object_class.yml b/benchmark/object_class.yml new file mode 100644 index 0000000000..1e5409d1e2 --- /dev/null +++ b/benchmark/object_class.yml @@ -0,0 +1,40 @@ +prelude: | + def get_class(obj) + i = 10_000 + while i > 0 + i -= 1 + # 100 times per loop + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; obj.class; + end + end + + class Obj + end + obj = Obj.new + + singleton = Obj.new + def singleton.bar + end + + extended = Obj.new + 2.times do + extended.extend Module.new + end + + immediate = 1.4 +benchmark: + obj: get_class(obj) + extended: get_class(extended) + singleton: get_class(singleton) + immediate: get_class(immediate) +loop_count: 1000 diff --git a/benchmark/set.yml b/benchmark/set.yml index 43217036e2..061509cb1f 100644 --- a/benchmark/set.yml +++ b/benchmark/set.yml @@ -259,7 +259,3 @@ benchmark: to_set_10: s1.to_set to_set_100: s2.to_set to_set_1000: s3.to_set - to_set_arg_0: s0.to_set set_subclass - to_set_arg_10: s1.to_set set_subclass - to_set_arg_100: s2.to_set set_subclass - to_set_arg_1000: s3.to_set set_subclass diff --git a/benchmark/string_casecmp.yml b/benchmark/string_casecmp.yml index 2354040a04..88a3555c8a 100644 --- a/benchmark/string_casecmp.yml +++ b/benchmark/string_casecmp.yml @@ -20,7 +20,9 @@ benchmark: casecmp-10: lstr10.casecmp(ustr10) casecmp-100: lstr100.casecmp(ustr100) casecmp-1000: lstr1000.casecmp(ustr1000) + casecmp-1000vs10: lstr1000.casecmp(ustr10) casecmp-nonascii1: lnonascii1.casecmp(unonascii1) casecmp-nonascii10: lnonascii10.casecmp(unonascii10) casecmp-nonascii100: lnonascii100.casecmp(unonascii100) casecmp-nonascii1000: lnonascii1000.casecmp(unonascii1000) + casecmp-nonascii1000vs10: lnonascii1000.casecmp(unonascii10) diff --git a/benchmark/struct_accessor.yml b/benchmark/struct_accessor.yml index 61176cfdd4..d95240e2dd 100644 --- a/benchmark/struct_accessor.yml +++ b/benchmark/struct_accessor.yml @@ -1,5 +1,12 @@ prelude: | C = Struct.new(:x) do + def initialize(...) + super + @ivar = 42 + end + + attr_accessor :ivar + class_eval <<-END def r #{'x;'*256} @@ -15,11 +22,16 @@ prelude: | m = method(:x=) #{'m.call(nil);'*256} end + def r_ivar + #{'ivar;'*256} + end END end + C.new(nil) # ensure common shape is known obj = C.new(nil) benchmark: member_reader: "obj.r" member_writer: "obj.w" member_reader_method: "obj.rm" member_writer_method: "obj.wm" + ivar_reader: "obj.r_ivar" diff --git a/benchmark/time_now.yml b/benchmark/time_now.yml index f6d6a31489..9336877cd4 100644 --- a/benchmark/time_now.yml +++ b/benchmark/time_now.yml @@ -1,3 +1,4 @@ benchmark: - 'Time.now' - 'Time.now(in: "+09:00")' + - 'Time.now.year' diff --git a/benchmark/vm_ivar_get.yml b/benchmark/vm_ivar_get.yml index 9174af6965..1e0dad665f 100644 --- a/benchmark/vm_ivar_get.yml +++ b/benchmark/vm_ivar_get.yml @@ -1,17 +1,75 @@ prelude: | class Example def initialize + @levar = 1 @v0 = 1 @v1 = 2 @v3 = 3 + end + + def get_value_loop + sum = 0 + + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + i += 1 + end + + return sum + end + + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + + def self.get_value_loop + sum = 0 + + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + sum += @levar + i += 1 + end + + return sum + end + end + + class GenExample < Time + def initialize @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 end def get_value_loop sum = 0 i = 0 - while i < 1000000 + while i < 100_000 # 10 times to de-emphasize loop overhead sum += @levar sum += @levar @@ -31,7 +89,12 @@ prelude: | end obj = Example.new + gen = GenExample.new benchmark: - vm_ivar_get: | + vm_ivar_get_on_obj: | obj.get_value_loop + vm_ivar_get_on_class: | + Example.get_value_loop + vm_ivar_get_on_generic: | + gen.get_value_loop loop_count: 100 diff --git a/benchmark/vm_ivar_set_on_instance.yml b/benchmark/vm_ivar_set_on_instance.yml index 91857b7742..6ce53a86ec 100644 --- a/benchmark/vm_ivar_set_on_instance.yml +++ b/benchmark/vm_ivar_set_on_instance.yml @@ -1,16 +1,44 @@ prelude: | class TheClass def initialize + @levar = 1 @v0 = 1 @v1 = 2 @v3 = 3 + end + + def set_value_loop + # 100k + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + i += 1 + end + end + end + + class Generic < Time + def initialize @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 end def set_value_loop - # 1M + # 100k i = 0 - while i < 1000000 + while i < 100_000 # 10 times to de-emphasize loop overhead @levar = i @levar = i @@ -28,8 +56,39 @@ prelude: | end obj = TheClass.new + gen_obj = Generic.new + + class SomeClass + @levar = 1 + @v0 = 1 + @v1 = 2 + @v3 = 3 + + def self.set_value_loop + # 100k + i = 0 + while i < 100_000 + # 10 times to de-emphasize loop overhead + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + @levar = i + i += 1 + end + end + end benchmark: vm_ivar_set_on_instance: | obj.set_value_loop + vm_ivar_set_on_generic: | + gen_obj.set_value_loop + vm_ivar_set_on_class: | + SomeClass.set_value_loop loop_count: 100 |
