@@ -10,11 +10,16 @@ def initialize(executable_names:, bench_data:, include_rss: false, include_pvalu
1010 @bench_data = bench_data
1111 @include_rss = include_rss
1212 @include_pvalue = include_pvalue
13+ @include_gc = detect_gc_data ( bench_data )
1314 @base_name = executable_names . first
1415 @other_names = executable_names [ 1 ..]
1516 @bench_names = compute_bench_names
1617 end
1718
19+ def include_gc?
20+ @include_gc
21+ end
22+
1823 def build
1924 table = [ build_header ]
2025 format = build_format
@@ -41,6 +46,10 @@ def build_header
4146 @executable_names . each do |name |
4247 header << "#{ name } (ms)"
4348 header << "RSS (MiB)" if @include_rss
49+ if @include_gc
50+ header << "#{ name } mark (ms)"
51+ header << "#{ name } sweep (ms)"
52+ end
4453 end
4554
4655 @other_names . each do |name |
@@ -60,6 +69,13 @@ def build_header
6069 end
6170 end
6271
72+ if @include_gc
73+ @other_names . each do |name |
74+ header << "mark #{ @base_name } /#{ name } "
75+ header << "sweep #{ @base_name } /#{ name } "
76+ end
77+ end
78+
6379 header
6480 end
6581
@@ -69,6 +85,10 @@ def build_format
6985 @executable_names . each do |_name |
7086 format << "%s"
7187 format << "%.1f" if @include_rss
88+ if @include_gc
89+ format << "%s"
90+ format << "%s"
91+ end
7292 end
7393
7494 @other_names . each do |_name |
@@ -88,6 +108,13 @@ def build_format
88108 end
89109 end
90110
111+ if @include_gc
112+ @other_names . each do |_name |
113+ format << "%s"
114+ format << "%s"
115+ end
116+ end
117+
91118 format
92119 end
93120
@@ -100,28 +127,45 @@ def build_row(bench_name)
100127 base_t , *other_ts = times_no_warmup
101128 base_rss , *other_rsss = rsss
102129
130+ if @include_gc
131+ marking_times = extract_gc_times ( bench_name , 'gc_marking_time_bench' )
132+ sweeping_times = extract_gc_times ( bench_name , 'gc_sweeping_time_bench' )
133+ base_mark , *other_marks = marking_times
134+ base_sweep , *other_sweeps = sweeping_times
135+ end
136+
103137 row = [ bench_name ]
104- build_base_columns ( row , base_t , base_rss )
105- build_comparison_columns ( row , other_ts , other_rsss )
138+ build_base_columns ( row , base_t , base_rss , base_mark , base_sweep )
139+ build_comparison_columns ( row , other_ts , other_rsss , other_marks , other_sweeps )
106140 build_ratio_columns ( row , base_t0 , other_t0s , base_t , other_ts )
107141 build_rss_ratio_columns ( row , base_rss , other_rsss )
142+ build_gc_ratio_columns ( row , base_mark , other_marks , base_sweep , other_sweeps )
108143
109144 row
110145 end
111146
112- def build_base_columns ( row , base_t , base_rss )
147+ def build_base_columns ( row , base_t , base_rss , base_mark , base_sweep )
113148 row << format_time_with_stddev ( base_t )
114149 row << base_rss if @include_rss
150+ if @include_gc
151+ row << format_time_with_stddev ( base_mark )
152+ row << format_time_with_stddev ( base_sweep )
153+ end
115154 end
116155
117- def build_comparison_columns ( row , other_ts , other_rsss )
118- other_ts . zip ( other_rsss ) . each do |other_t , other_rss |
156+ def build_comparison_columns ( row , other_ts , other_rsss , other_marks , other_sweeps )
157+ other_ts . each_with_index do |other_t , i |
119158 row << format_time_with_stddev ( other_t )
120- row << other_rss if @include_rss
159+ row << other_rsss [ i ] if @include_rss
160+ if @include_gc
161+ row << format_time_with_stddev ( other_marks [ i ] )
162+ row << format_time_with_stddev ( other_sweeps [ i ] )
163+ end
121164 end
122165 end
123166
124167 def format_time_with_stddev ( values )
168+ return "N/A" if values . nil? || values . empty?
125169 "%.1f ± %.1f%%" % [ mean ( values ) , stddev_percent ( values ) ]
126170 end
127171
@@ -147,6 +191,26 @@ def build_rss_ratio_columns(row, base_rss, other_rsss)
147191 end
148192 end
149193
194+ def build_gc_ratio_columns ( row , base_mark , other_marks , base_sweep , other_sweeps )
195+ return unless @include_gc
196+
197+ ( other_marks || [ ] ) . each do |other_mark |
198+ row << gc_ratio ( base_mark , other_mark )
199+ end
200+ ( other_sweeps || [ ] ) . each do |other_sweep |
201+ row << gc_ratio ( base_sweep , other_sweep )
202+ end
203+ end
204+
205+ def gc_ratio ( base , other )
206+ if base . nil? || base . empty? || other . nil? || other . empty? ||
207+ mean ( other ) == 0.0
208+ return "N/A"
209+ end
210+ pval = Stats . welch_p_value ( base , other )
211+ format_ratio ( mean ( base ) / mean ( other ) , pval )
212+ end
213+
150214 def format_ratio ( ratio , pval )
151215 sym = significance_symbol ( pval )
152216 formatted = "%.3f" % ratio
@@ -211,6 +275,16 @@ def extract_rss_values(bench_name)
211275 end
212276 end
213277
278+ def extract_gc_times ( bench_name , key )
279+ @executable_names . map do |name |
280+ bench_data_for ( name , bench_name ) [ key ] || [ ]
281+ end
282+ end
283+
284+ def detect_gc_data ( bench_data )
285+ bench_data . values . any? { |benchmarks | benchmarks . values . any? { |d | d . is_a? ( Hash ) && d . key? ( 'gc_marking_time_bench' ) } }
286+ end
287+
214288 def bench_data_for ( name , bench_name )
215289 @bench_data [ name ] [ bench_name ]
216290 end
0 commit comments