Skip to content

Commit b295277

Browse files
Introduce ractor and ractor-only categories
This commit modifies the benchmark runner to add 2 new categories: --category=ractor-only Runs only those benchmarks in benchmarks-ractor using the Ractor harness. --category=ractor In addition to the ractor-only benchmarks, this will run benchmarks specified in benchmarks.yml with `ractor: true` using the Ractor harness. In addition to this we've modified the burn in and run once scripts to use the new harnesses and categories too Co-Authored-By: Luke Gruber <[email protected]>
1 parent 5cab2e6 commit b295277

File tree

4 files changed

+199
-77
lines changed

4 files changed

+199
-77
lines changed

benchmarks.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ mail:
3131
psych-load:
3232
desc: psych-load repeatedly loads a small selection of YAML files taken from various OSS projects.
3333
category: headline
34+
ractor: true
3435
railsbench:
3536
desc: railsbench is a read-only tiny SQLite-backed Rails app, querying a small selection of .html.erb routes and JSON routes.
3637
category: headline
@@ -54,16 +55,20 @@ binarytrees:
5455
desc: binarytrees from the Computer Language Benchmarks Game.
5556
blurhash:
5657
desc: blurhash (blurred preview image) calculation
58+
ractor: true
5759
erubi:
5860
desc: erubi compiles a simple Erb template into a method with erubi, then times evaluating that method.
61+
ractor: true
5962
etanni:
6063
desc: etanni is an older, extremely simple template-lang format that basically turns your template into an "eval" with a lot of heredocs.
6164
fannkuchredux:
6265
desc: fannkuchredux from the Computer Language Benchmarks Game.
66+
ractor: true
6367
fluentd:
6468
desc: fluentd is a log collector, which parses logs in a server and forwards them to various destinations.
6569
graphql:
6670
desc: GraphQL gem parsing a large file, uses Racc which has some Ruby->native->Ruby calls
71+
ractor: true
6772
graphql-native:
6873
desc: GraphQL gem parsing a large file, but using a native parser
6974
knucleotide:
@@ -72,26 +77,33 @@ lee:
7277
desc: lee is a circuit-board layout solver, deployed in a plausibly reality-like way
7378
matmul:
7479
desc: matrix multiplication benchmark
80+
ractor: true
7581
nbody:
7682
desc: nbody from the Computer Language Benchmarks Game.
7783
nqueens:
7884
desc: solver for the N-Queens problem
85+
ractor: true
7986
optcarrot:
8087
desc: optcarrot is a functional headless NES emulator, run on a specific game cartridge for a specific number of frames.
8188
protoboeuf:
8289
desc: protoboeuf (pure-Ruby protobuf) message decoding
90+
ractor: true
8391
protoboeuf-encode:
8492
desc: protoboeuf (pure-Ruby protobuf) message encoding
93+
ractor: true
8594
rack:
8695
desc: test the performance of the Rack framework with barely any routing.
8796
ruby-json:
8897
desc: an optimized version of the json_pure gem's pure Ruby JSON parser.
98+
ractor: true
8999
rubyboy:
90100
desc: Rubyboy is a functional headless GameBoy emulator, run on a specific game cartridge for a specific number of frames.
101+
ractor: true
91102
rubykon:
92103
desc: Ruby solver for Go (the boardgame.) Runs many iterations forward from an initial starting board.
93104
sudoku:
94105
desc: sudoku solver
106+
ractor: true
95107
tinygql:
96108
desc: TinyGQL gem parsing a large file in pure Ruby
97109

@@ -102,14 +114,17 @@ tinygql:
102114
desc: 30k_ifelse tests thousands of nested methods containing simple if/else statements.
103115
category: micro
104116
single_file: true
117+
ractor: true
105118
30k_methods:
106119
desc: 30k_methods tests thousands of nested method calls that mostly just call out to other single-call methods.
107120
category: micro
108121
single_file: true
122+
ractor: true
109123
attr_accessor:
110124
desc: attr_accessor tests the performance of getting instance variable values via an attr_accessor imemo.
111125
category: micro
112126
single_file: true
127+
ractor: true
113128
cfunc_itself:
114129
desc: cfunc_itself just calls the 'itself' method many, many times.
115130
category: micro
@@ -130,10 +145,12 @@ fib:
130145
desc: Fib is a simple exponential-time recursive Fibonacci number generator.
131146
category: micro
132147
single_file: true
148+
ractor: true
133149
getivar:
134150
desc: getivar tests the performance of getting instance variable values.
135151
category: micro
136152
single_file: true
153+
ractor: true
137154
keyword_args:
138155
desc: keyword_args tests the performance of method calls with keyword arguments.
139156
category: micro
@@ -142,10 +159,12 @@ loops-times:
142159
desc: nested loop Integer#times and array access microbenchmark
143160
category: micro
144161
single_file: true
162+
ractor: true
145163
object-new:
146164
desc: instantiate a new object in a loop to test allocation performance
147165
category: micro
148166
single_file: true
167+
ractor: true
149168
respond_to:
150169
desc: respond_to tests the performance of the respond_to? method.
151170
category: micro
@@ -154,6 +173,7 @@ ruby-xor:
154173
desc: pure-Ruby string XOR microbenchmark, analogous to xorcist C extension.
155174
category: micro
156175
single_file: true
176+
ractor: true
157177
setivar:
158178
desc: setivar tests the performance of setting instance variable values.
159179
category: micro
@@ -166,14 +186,18 @@ setivar_young:
166186
desc: setivar_object tests the performance of setting instance variables to an object, to test write barrier speed on young objects.
167187
category: micro
168188
single_file: true
189+
ractor: true
169190
str_concat:
170191
desc: str_concat tests the performance of string concatenation in multiple different encodings.
171192
category: micro
172193
single_file: true
194+
ractor: true
173195
throw:
174196
desc: microbenchmark for the throw instruction and stack unwinding.
175197
category: micro
176198
single_file: true
199+
ractor: true
200+
177201
#
178202
# Ractor-only benchmarks
179203
#

burn_in.rb

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
args.num_long_runs = v.to_i
4242
end
4343

44-
opts.on("--category=headline,other,micro", "when given, only benchmarks with specified categories will run") do |v|
44+
opts.on("--category=headline,other,micro,ractor,ractor-only", "when given, only benchmarks with specified categories will run") do |v|
4545
args.categories = v.split(",")
4646
end
4747

@@ -59,11 +59,18 @@ def free_file_path(parent_dir, name_prefix)
5959
end
6060
end
6161

62-
def run_benchmark(bench_name, no_yjit, logs_path, run_time, ruby_version)
62+
def run_benchmark(bench_id, no_yjit, logs_path, run_time, ruby_version)
6363
# Determine the path to the benchmark script
64-
script_path = File.join('benchmarks', bench_name, 'benchmark.rb')
64+
bench_name = bench_id.sub('ractor/', '')
65+
bench_dir, harness = if bench_name == bench_id
66+
['benchmarks', 'harness']
67+
else
68+
['benchmarks-ractor', 'harness-ractor']
69+
end
70+
71+
script_path = File.join(bench_dir, bench_name, 'benchmark.rb')
6572
if not File.exist?(script_path)
66-
script_path = File.join('benchmarks', bench_name + '.rb')
73+
script_path = File.join(bench_dir, bench_name + '.rb')
6774
end
6875

6976
# Assemble random environment variable options to test
@@ -101,7 +108,7 @@ def run_benchmark(bench_name, no_yjit, logs_path, run_time, ruby_version)
101108
cmd = [
102109
'ruby',
103110
*test_options,
104-
"-Iharness",
111+
"-I#{harness}",
105112
script_path,
106113
].compact
107114
cmd_str = cmd.shelljoin
@@ -133,7 +140,7 @@ def run_benchmark(bench_name, no_yjit, logs_path, run_time, ruby_version)
133140
puts "ERROR"
134141

135142
# Write command executed and output
136-
out_path = free_file_path(logs_path, "error_#{bench_name}")
143+
out_path = free_file_path(logs_path, "error_#{bench_name.gsub('/', '_')}")
137144
puts "writing output file #{out_path}"
138145
contents = ruby_version + "\n\n" + "pid #{status.pid}\n" + user_cmd_str + "\n\n" + output
139146
File.write(out_path, contents)
@@ -191,11 +198,38 @@ def test_loop(bench_names, no_yjit, logs_path, run_time, ruby_version)
191198

192199
# Extract the names of benchmarks in the categories we want
193200
metadata = YAML.load_file('benchmarks.yml')
194-
metadata = metadata.filter do |bench_name, entry|
195-
category = entry.fetch('category', 'other')
196-
args.categories.include? category
201+
bench_names = []
202+
203+
if args.categories.include?('ractor-only')
204+
# Only include benchmarks with ractor/ prefix (from benchmarks-ractor directory)
205+
bench_names = metadata.keys.select { |name| name.start_with?('ractor/') }
206+
elsif args.categories.include?('ractor')
207+
# Include both ractor/ prefixed benchmarks and those with ractor: true
208+
metadata.each do |name, entry|
209+
if name.start_with?('ractor/') || entry['ractor']
210+
bench_names << name
211+
end
212+
end
213+
214+
# Also include regular category benchmarks if other categories are specified
215+
if args.categories.any? { |cat| ['headline', 'other', 'micro'].include?(cat) }
216+
metadata.each do |name, entry|
217+
category = entry.fetch('category', 'other')
218+
if args.categories.include?(category) && !bench_names.include?(name)
219+
bench_names << name
220+
end
221+
end
222+
end
223+
else
224+
# Regular category filtering
225+
metadata.each do |name, entry|
226+
category = entry.fetch('category', 'other')
227+
if args.categories.include?(category)
228+
bench_names << name
229+
end
230+
end
197231
end
198-
bench_names = metadata.map { |name, entry| name }
232+
199233
bench_names.sort!
200234

201235
# Fork the test processes

0 commit comments

Comments
 (0)