You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0dbdc38
Browse filesBrowse the repository at this point in the historyBrowse files
Show GC results for every ruby when comparing builds
With three or more rubies, the GC time ratios and GC counts tables only
had one row per comparison (base → other), so no ruby had its own row
and the baseline appeared only on the left of each arrow.
harness-gc also printed 0 live and free slots in the heap utilisation
table on Ruby 3.4, because GC.stat_heap before 4.0 has no
heap_live_slots or heap_free_slots.
This commit adds a "GC per ruby" table that prints before the GC time
ratios table. It has one row per ruby per benchmark, including the
base, with the same absolute columns as the single-ruby GC summary. The
table is left out when only one ruby runs, because the GC summary
already shows those values. A benchmark is left out only when no ruby
has GC activity.
The legend and GC metric notes now say which table each sentence
describes, and they describe each table's own skip rule. The Ractor GC
ms/worker note now appears whenever a table shows that column.
After the full GC, harness-gc now derives live and free slots from the
per-heap total_allocated_objects and total_freed_objects counters when
GC.stat_heap does not report them.
per_ruby_headers=gc_table_list.select{ |gc_table| gc_table[:name] == 'GC per ruby'}.flat_map{ |gc_table| gc_table[:rows].first}
77
79
sections.eachdo |section|
78
80
title=section[:title]
79
81
output_str << "#{title}:\n"iftitle
@@ -93,10 +95,11 @@ def build_output_text(ruby_descriptions, table, format, bench_failures, include_
93
95
end
94
96
end
95
97
ifhas_gc_summary
98
+
output_str << "- GC per ruby shows the mean GC values per benchmark iteration for each ruby. These values are not ratios. Benchmarks with no GC activity on any ruby are omitted.\n"unlessper_ruby_headers.empty?
96
99
output_str << "- GC time ratios are #{base_name}/comparison; above 1 means the comparison spent less GC time.\n"
97
100
output_str << "- gc/iter, mark/iter, and sweep/iter compare total GC (or phase) time per benchmark iteration, so they include both per-GC cost and GC frequency changes.\n"
98
101
output_str << "- gc/GC, mark/GC, and sweep/GC divide average GC (or phase) time by the same run's GCs/iter count; they are not complete per-cycle attribution of process-wide GC.\n"
99
-
output_str << "- GC counts show #{base_name} → comparison values, not ratios. Rows with no GC activity are omitted.\n"
102
+
output_str << "- GC counts show #{base_name} → comparison values, not ratios. In GC time ratios and GC counts, a row is omitted when neither #{base_name} nor the comparison has GC activity.\n"
100
103
end
101
104
ifhas_memory_summary
102
105
output_str << "- Scenario memory shows #{base_name} → comparison values, not ratios. Lower is better.\n"
@@ -105,10 +108,13 @@ def build_output_text(ruby_descriptions, table, format, bench_failures, include_
105
108
output_str << "- ***: p < 0.001, **: p < 0.01, *: p < 0.05 (Welch's t-test)\n"
output_str << "- compacts*: the main Ractor's GC.stat(:compact_count) delta per iteration. Every global compacting cycle increments compact_count in every object space. Do not sum it across workers.#{other_names.empty? ? '' : " Comparison tables show #{base_name} → comparison values."}\n"
114
+
compaction_note= +""
115
+
compaction_note << " GC counts show #{base_name} → comparison values."unlessother_names.empty?
116
+
compaction_note << " GC per ruby shows the value for each ruby."ifper_ruby_headers.include?('compacts*')
117
+
output_str << "- compacts*: the main Ractor's GC.stat(:compact_count) delta per iteration. Every global compacting cycle increments compact_count in every object space. Do not sum it across workers.#{compaction_note}\n"
@@ -118,7 +124,7 @@ def build_output_text(ruby_descriptions, table, format, bench_failures, include_
118
124
output_str << "Ractor GC scope note:\n"
119
125
scope_columns= +"- Tables marked worker sum add Ractor-local counters and GC times across the sampled workers of each iteration"
120
126
scope_columns << (worker_mode ? "; the main Ractor performs the count-0 workload of per-worker benchmarks." : ".")
121
-
scope_columns << " GC ms/worker divides each iteration's worker-sum GC time by its sampled worker count, then averages."ifother_names.empty?
127
+
scope_columns << " GC ms/worker divides each iteration's worker-sum GC time by its sampled worker count, then averages."ifgc_headers.include?('GC ms/worker')
122
128
output_str << "#{scope_columns} Controller snapshots and per-worker heap detail are in the JSON output, not these tables.\n"
123
129
output_str << "- Ruby's Ractor-retirement GC (after a worker's stack is torn down) is not sampled."
124
130
output_str << " Ractors created by the workload of a per-worker benchmark are not sampled."ifworker_mode
Copy file name to clipboardExpand all lines: test/benchmark_runner_test.rb
+78-3Lines changed: 78 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -524,7 +524,8 @@ def git(dir, *args)
524
524
assert_includesresult,"- compacts*: the main Ractor's GC.stat(:compact_count) delta per iteration."
525
525
assert_includesresult,'Every global compacting cycle increments compact_count in every object space.'
526
526
assert_includesresult,'Do not sum it across workers.'
527
-
assert_includesresult,'Comparison tables show ruby-base → comparison values.'
527
+
assert_includesresult,'GC counts show ruby-base → comparison values.'
528
+
refute_includesresult,'GC per ruby shows the value for each ruby.'
528
529
refute_includesresult,'global GCs/iter'
529
530
end
530
531
@@ -546,7 +547,7 @@ def git(dir, *args)
546
547
refute_includesresult,'Legend:'
547
548
assert_includesresult,"GC metric notes:\n"
548
549
assert_includesresult,"- compacts*: the main Ractor's GC.stat(:compact_count) delta per iteration."
549
-
refute_includesresult,'Comparison tables show'
550
+
refute_includesresult,'GC counts show'
550
551
refute_includesresult,'global GCs/iter'
551
552
end
552
553
@@ -573,7 +574,7 @@ def git(dir, *args)
573
574
574
575
refute_includesresult,'GC metric notes:'
575
576
assert_includesresult,"the same run's GCs/iter count"
576
-
assert_includesresult,'GC counts show ruby-base → comparison values, not ratios'
577
+
assert_includesresult,'GC counts show ruby-base → comparison values, not ratios. In GC time ratios and GC counts, a row is omitted when neither ruby-base nor the comparison has GC activity.'
577
578
end
578
579
579
580
it'omits the Ractor scope note when the section rendered no GC table'do
@@ -597,6 +598,80 @@ def git(dir, *args)
597
598
refute_includesresult,'Ractor GC scope note:'
598
599
end
599
600
601
+
it'prints the GC per ruby table before the GC ratio table, with its legend line'do
assert_includesresult,'- GC per ruby shows the mean GC values per benchmark iteration for each ruby. These values are not ratios. Benchmarks with no GC activity on any ruby are omitted.'
642
+
assert_includesresult,'Do not sum it across workers. GC counts show master → comparison values. GC per ruby shows the value for each ruby.'
643
+
refute_includesresult,'GC per ruby (harness):'
644
+
end
645
+
646
+
it'explains GC ms/worker in the Ractor scope note when only the GC per ruby table shows it'do
0 commit comments