Skip to content

Commit 43dc4a5

Browse files
Merge pull request #482 from ruby/mvh-rss-ratio
When --rss is used, include an "RSS ratio" column
2 parents 60d93c0 + f80ecd4 commit 43dc4a5

File tree

5 files changed

+109
-4
lines changed

5 files changed

+109
-4
lines changed

lib/benchmark_runner.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def write_csv(output_path, ruby_descriptions, table)
4848
end
4949

5050
# Build output text string with metadata, table, and legend
51-
def build_output_text(ruby_descriptions, table, format, bench_failures)
51+
def build_output_text(ruby_descriptions, table, format, bench_failures, include_rss: false)
5252
base_name, *other_names = ruby_descriptions.keys
5353

5454
output_str = +""
@@ -65,6 +65,9 @@ def build_output_text(ruby_descriptions, table, format, bench_failures)
6565
other_names.each do |name|
6666
output_str << "- #{name} 1st itr: ratio of #{base_name}/#{name} time for the first benchmarking iteration.\n"
6767
output_str << "- #{base_name}/#{name}: ratio of #{base_name}/#{name} time. Higher is better for #{name}. Above 1 represents a speedup.\n"
68+
if include_rss
69+
output_str << "- RSS #{base_name}/#{name}: ratio of #{base_name}/#{name} RSS. Higher is better for #{name}. Above 1 means lower memory usage.\n"
70+
end
6871
end
6972
output_str << "- ***: p < 0.001, **: p < 0.01, *: p < 0.05 (Welch's t-test)\n"
7073
end

lib/benchmark_runner/cli.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def run
8585
BenchmarkRunner.write_csv(output_path, ruby_descriptions, table)
8686

8787
# Save the output in a text file that we can easily refer to
88-
output_str = BenchmarkRunner.build_output_text(ruby_descriptions, table, format, bench_failures)
88+
output_str = BenchmarkRunner.build_output_text(ruby_descriptions, table, format, bench_failures, include_rss: args.rss)
8989
out_txt_path = output_path + ".txt"
9090
File.open(out_txt_path, "w") { |f| f.write output_str }
9191

lib/results_table_builder.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ def build_header
5454
end
5555
end
5656

57+
if @include_rss
58+
@other_names.each do |name|
59+
header << "RSS #{@base_name}/#{name}"
60+
end
61+
end
62+
5763
header
5864
end
5965

@@ -76,6 +82,12 @@ def build_format
7682
end
7783
end
7884

85+
if @include_rss
86+
@other_names.each do |_name|
87+
format << "%.3f"
88+
end
89+
end
90+
7991
format
8092
end
8193

@@ -92,6 +104,7 @@ def build_row(bench_name)
92104
build_base_columns(row, base_t, base_rss)
93105
build_comparison_columns(row, other_ts, other_rsss)
94106
build_ratio_columns(row, base_t0, other_t0s, base_t, other_ts)
107+
build_rss_ratio_columns(row, base_rss, other_rsss)
95108

96109
row
97110
end
@@ -124,6 +137,14 @@ def build_ratio_columns(row, base_t0, other_t0s, base_t, other_ts)
124137
end
125138
end
126139

140+
def build_rss_ratio_columns(row, base_rss, other_rsss)
141+
return unless @include_rss
142+
143+
other_rsss.each do |other_rss|
144+
row << base_rss / other_rss
145+
end
146+
end
147+
127148
def format_ratio(ratio, pval)
128149
sym = significance_symbol(pval)
129150
formatted = "%.3f" % ratio

test/benchmark_runner_test.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,44 @@
390390
assert_includes result, "- ***: p < 0.001, **: p < 0.01, *: p < 0.05 (Welch's t-test)"
391391
end
392392

393+
it 'includes RSS ratio legend when include_rss is true' do
394+
ruby_descriptions = {
395+
'ruby-base' => 'ruby 3.3.0',
396+
'ruby-yjit' => 'ruby 3.3.0 +YJIT'
397+
}
398+
table = [
399+
['bench', 'ruby-base (ms)', 'stddev (%)', 'RSS (MiB)', 'ruby-yjit (ms)', 'stddev (%)', 'RSS (MiB)', 'ruby-yjit 1st itr', 'ruby-base/ruby-yjit', 'RSS ruby-base/ruby-yjit'],
400+
['fib', '100.0', '5.0', '10.0', '50.0', '3.0', '12.0', '2.000', '2.000', '0.833']
401+
]
402+
format = ['%s', '%.1f', '%.1f', '%.1f', '%.1f', '%.1f', '%.1f', '%.3f', '%s', '%.3f']
403+
bench_failures = {}
404+
405+
result = BenchmarkRunner.build_output_text(
406+
ruby_descriptions, table, format, bench_failures, include_rss: true
407+
)
408+
409+
assert_includes result, '- RSS ruby-base/ruby-yjit: ratio of ruby-base/ruby-yjit RSS. Higher is better for ruby-yjit. Above 1 means lower memory usage.'
410+
end
411+
412+
it 'omits RSS ratio legend when include_rss is false' do
413+
ruby_descriptions = {
414+
'ruby-base' => 'ruby 3.3.0',
415+
'ruby-yjit' => 'ruby 3.3.0 +YJIT'
416+
}
417+
table = [
418+
['bench', 'ruby-base (ms)', 'stddev (%)', 'ruby-yjit (ms)', 'stddev (%)'],
419+
['fib', '100.0', '5.0', '50.0', '3.0']
420+
]
421+
format = ['%s', '%.1f', '%.1f', '%.1f', '%.1f']
422+
bench_failures = {}
423+
424+
result = BenchmarkRunner.build_output_text(
425+
ruby_descriptions, table, format, bench_failures
426+
)
427+
428+
refute_includes result, 'RSS ruby-base/ruby-yjit'
429+
end
430+
393431
it 'includes formatted table in output' do
394432
ruby_descriptions = { 'ruby' => 'ruby 3.3.0' }
395433
table = [

test/results_table_builder_test.rb

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,56 @@
8787

8888
table, format = builder.build
8989

90+
# No RSS ratio column with a single executable
9091
assert_equal ['bench', 'ruby (ms)', 'stddev (%)', 'RSS (MiB)'], table[0]
91-
9292
assert_equal ['%s', '%.1f', '%.1f', '%.1f'], format
93-
9493
assert_in_delta 10.0, table[1][3], 0.1
9594
end
9695

96+
it 'includes RSS ratio columns when include_rss is true with multiple executables' do
97+
executable_names = ['ruby', 'ruby-yjit']
98+
bench_data = {
99+
'ruby' => {
100+
'fib' => {
101+
'warmup' => [0.1],
102+
'bench' => [0.1, 0.11, 0.09],
103+
'rss' => 1024 * 1024 * 10
104+
}
105+
},
106+
'ruby-yjit' => {
107+
'fib' => {
108+
'warmup' => [0.05],
109+
'bench' => [0.05, 0.06, 0.04],
110+
'rss' => 1024 * 1024 * 20
111+
}
112+
}
113+
}
114+
115+
builder = ResultsTableBuilder.new(
116+
executable_names: executable_names,
117+
bench_data: bench_data,
118+
include_rss: true
119+
)
120+
121+
table, format = builder.build
122+
123+
expected_header = [
124+
'bench',
125+
'ruby (ms)', 'stddev (%)', 'RSS (MiB)',
126+
'ruby-yjit (ms)', 'stddev (%)', 'RSS (MiB)',
127+
'ruby-yjit 1st itr',
128+
'ruby/ruby-yjit',
129+
'RSS ruby/ruby-yjit'
130+
]
131+
assert_equal expected_header, table[0]
132+
133+
expected_format = ['%s', '%.1f', '%.1f', '%.1f', '%.1f', '%.1f', '%.1f', '%.3f', '%s', '%.3f']
134+
assert_equal expected_format, format
135+
136+
# RSS ratio: 10 MiB / 20 MiB = 0.5
137+
assert_in_delta 0.5, table[1].last, 0.01
138+
end
139+
97140
it 'skips benchmarks with missing data' do
98141
executable_names = ['ruby', 'ruby-yjit']
99142
bench_data = {

0 commit comments

Comments
 (0)