15
15
@dataclass
16
16
class BenchmarkMetadata :
17
17
unit : str
18
+ suite : str
18
19
lower_is_better : bool
19
20
20
21
@dataclass
@@ -26,6 +27,7 @@ class BenchmarkSeries:
26
27
@dataclass
27
28
class BenchmarkChart :
28
29
label : str
30
+ suite : str
29
31
html : str
30
32
31
33
def tooltip_css () -> str :
@@ -74,13 +76,6 @@ def create_time_series_chart(benchmarks: list[BenchmarkSeries], github_repo: str
74
76
targets = targets )
75
77
mpld3 .plugins .connect (fig , tooltip )
76
78
77
- # This is so that the stddev doesn't fill the entire y axis on the chart
78
- if all_values and all_stddevs :
79
- max_value = max (all_values )
80
- min_value = min (all_values )
81
- max_stddev = max (all_stddevs )
82
- ax .set_ylim (min_value - 3 * max_stddev , max_value + 3 * max_stddev )
83
-
84
79
ax .set_title (benchmark .label , pad = 20 )
85
80
performance_indicator = "lower is better" if benchmark .metadata .lower_is_better else "higher is better"
86
81
ax .text (0.5 , 1.05 , f"({ performance_indicator } )" ,
@@ -98,7 +93,7 @@ def create_time_series_chart(benchmarks: list[BenchmarkSeries], github_repo: str
98
93
ax .xaxis .set_major_formatter (mdates .ConciseDateFormatter ('%Y-%m-%d %H:%M:%S' ))
99
94
100
95
plt .tight_layout ()
101
- html_charts .append (BenchmarkChart (html = mpld3 .fig_to_html (fig ), label = benchmark .label ))
96
+ html_charts .append (BenchmarkChart (html = mpld3 .fig_to_html (fig ), label = benchmark .label , suite = benchmark . metadata . suite ))
102
97
plt .close (fig )
103
98
104
99
return html_charts
@@ -119,7 +114,7 @@ def create_explicit_groups(benchmark_runs: list[BenchmarkRun], compare_names: li
119
114
if res .explicit_group != '' :
120
115
if res .explicit_group not in groups :
121
116
groups [res .explicit_group ] = ExplicitGroup (name = res .explicit_group , nnames = len (compare_names ),
122
- metadata = BenchmarkMetadata (unit = res .unit , lower_is_better = res .lower_is_better ),
117
+ metadata = BenchmarkMetadata (unit = res .unit , lower_is_better = res .lower_is_better , suite = res . suite ),
123
118
runs = {})
124
119
125
120
group = groups [res .explicit_group ]
@@ -207,7 +202,7 @@ def create_grouped_bar_charts(groups: list[ExplicitGroup]) -> list[BenchmarkChar
207
202
color = '#666666' )
208
203
209
204
plt .tight_layout ()
210
- html_charts .append (BenchmarkChart (label = group .name , html = mpld3 .fig_to_html (fig )))
205
+ html_charts .append (BenchmarkChart (label = group .name , html = mpld3 .fig_to_html (fig ), suite = group . metadata . suite ))
211
206
plt .close (fig )
212
207
213
208
return html_charts
@@ -224,7 +219,8 @@ def process_benchmark_data(benchmark_runs: list[BenchmarkRun], compare_names: li
224
219
if result .label not in benchmark_metadata :
225
220
benchmark_metadata [result .label ] = BenchmarkMetadata (
226
221
unit = result .unit ,
227
- lower_is_better = result .lower_is_better
222
+ lower_is_better = result .lower_is_better ,
223
+ suite = result .suite
228
224
)
229
225
230
226
result .date = run .date
@@ -249,12 +245,15 @@ def generate_html(benchmark_runs: list[BenchmarkRun], github_repo: str, compare_
249
245
benchmarks = process_benchmark_data (benchmark_runs , compare_names )
250
246
251
247
timeseries = create_time_series_chart (benchmarks , github_repo )
252
- timeseries_charts_html = '\n ' .join (f'<div class="chart" data-label="{ ts .label } "><div>{ ts .html } </div></div>' for ts in timeseries )
248
+ timeseries_charts_html = '\n ' .join (f'<div class="chart" data-label="{ ts .label } " data-suite=" { ts . suite } " ><div>{ ts .html } </div></div>' for ts in timeseries )
253
249
254
250
explicit_groups = create_explicit_groups (benchmark_runs , compare_names )
255
251
256
252
bar_charts = create_grouped_bar_charts (explicit_groups )
257
- bar_charts_html = '\n ' .join (f'<div class="chart" data-label="{ bc .label } "><div>{ bc .html } </div></div>' for bc in bar_charts )
253
+ bar_charts_html = '\n ' .join (f'<div class="chart" data-label="{ bc .label } " data-suite="{ bc .suite } "><div>{ bc .html } </div></div>' for bc in bar_charts )
254
+
255
+ suite_names = {t .suite for t in timeseries }
256
+ suite_checkboxes_html = ' ' .join (f'<label><input type="checkbox" class="suite-checkbox" data-suite="{ suite } " checked> { suite } </label>' for suite in suite_names )
258
257
259
258
html_template = f"""
260
259
<!DOCTYPE html>
@@ -317,6 +316,16 @@ def generate_html(benchmark_runs: list[BenchmarkRun], github_repo: str, compare_
317
316
width: 400px;
318
317
max-width: 100%;
319
318
}}
319
+ .suite-filter-container {{
320
+ text-align: center;
321
+ margin-bottom: 24px;
322
+ padding: 16px;
323
+ background: #e9ecef;
324
+ border-radius: 8px;
325
+ }}
326
+ .suite-checkbox {{
327
+ margin: 0 8px;
328
+ }}
320
329
details {{
321
330
margin-bottom: 24px;
322
331
}}
@@ -342,54 +351,87 @@ def generate_html(benchmark_runs: list[BenchmarkRun], github_repo: str, compare_
342
351
function filterCharts() {{
343
352
const regexInput = document.getElementById('bench-filter').value;
344
353
const regex = new RegExp(regexInput, 'i');
354
+ const activeSuites = Array.from(document.querySelectorAll('.suite-checkbox:checked')).map(checkbox => checkbox.getAttribute('data-suite'));
345
355
const charts = document.querySelectorAll('.chart');
346
- let timeseriesVisible = false;
347
- let barChartsVisible = false;
348
356
349
357
charts.forEach(chart => {{
350
358
const label = chart.getAttribute('data-label');
351
- if (regex.test(label)) {{
359
+ const suite = chart.getAttribute('data-suite');
360
+ if (regex.test(label) && activeSuites.includes(suite)) {{
352
361
chart.style.display = '';
353
- if (chart.closest('.timeseries')) {{
354
- timeseriesVisible = true;
355
- }} else if (chart.closest('.bar-charts')) {{
356
- barChartsVisible = true;
357
- }}
358
362
}} else {{
359
363
chart.style.display = 'none';
360
364
}}
361
365
}});
362
366
363
- updateURL(regexInput);
364
-
365
- document.querySelector('.timeseries').open = timeseriesVisible;
366
- document.querySelector('.bar-charts').open = barChartsVisible;
367
+ updateURL();
367
368
}}
368
369
369
- function updateURL(regex ) {{
370
+ function updateURL() {{
370
371
const url = new URL(window.location);
372
+ const regex = document.getElementById('bench-filter').value;
373
+ const activeSuites = Array.from(document.querySelectorAll('.suite-checkbox:checked')).map(checkbox => checkbox.getAttribute('data-suite'));
374
+
371
375
if (regex) {{
372
376
url.searchParams.set('regex', regex);
373
377
}} else {{
374
378
url.searchParams.delete('regex');
375
379
}}
380
+
381
+ if (activeSuites.length > 0) {{
382
+ url.searchParams.set('suites', activeSuites.join(','));
383
+ }} else {{
384
+ url.searchParams.delete('suites');
385
+ }}
386
+
376
387
history.replaceState(null, '', url);
377
388
}}
378
389
379
390
document.addEventListener('DOMContentLoaded', (event) => {{
380
391
const regexParam = getQueryParam('regex');
392
+ const suitesParam = getQueryParam('suites');
393
+
381
394
if (regexParam) {{
382
395
document.getElementById('bench-filter').value = regexParam;
383
- filterCharts();
384
396
}}
397
+
398
+ const suiteCheckboxes = document.querySelectorAll('.suite-checkbox');
399
+ if (suitesParam) {{
400
+ const suites = suitesParam.split(',');
401
+ suiteCheckboxes.forEach(checkbox => {{
402
+ if (suites.includes(checkbox.getAttribute('data-suite'))) {{
403
+ checkbox.checked = true;
404
+ }} else {{
405
+ checkbox.checked = false;
406
+ }}
407
+ }});
408
+ }} else {{
409
+ suiteCheckboxes.forEach(checkbox => {{
410
+ checkbox.checked = true;
411
+ }});
412
+ }}
413
+ filterCharts();
414
+
415
+ suiteCheckboxes.forEach(checkbox => {{
416
+ checkbox.addEventListener('change', () => {{
417
+ filterCharts();
418
+ }});
419
+ }});
420
+
421
+ document.getElementById('bench-filter').addEventListener('input', () => {{
422
+ filterCharts();
423
+ }});
385
424
}});
386
425
</script>
387
426
</head>
388
427
<body>
389
428
<div class="container">
390
429
<h1>Benchmark Results</h1>
391
430
<div class="filter-container">
392
- <input type="text" id="bench-filter" placeholder="Regex..." oninput="filterCharts()">
431
+ <input type="text" id="bench-filter" placeholder="Regex...">
432
+ </div>
433
+ <div class="suite-filter-container">
434
+ { suite_checkboxes_html }
393
435
</div>
394
436
<details class="timeseries">
395
437
<summary>Historical Results</summary>
0 commit comments