mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 10:05:28 +03:00
94 lines
3.1 KiB
Python
94 lines
3.1 KiB
Python
__all__ = ["DiagramGenerator"]
|
|
|
|
from pathlib import Path
|
|
|
|
import cairosvg
|
|
import pygal
|
|
from pygal.style import Style
|
|
|
|
from ..benchmarks.core.models import BenchmarkGroupResult
|
|
|
|
|
|
class DiagramGenerator:
|
|
def __init__(self, output_dir: Path | str) -> None:
|
|
self.output_dir: Path = Path(output_dir) if isinstance(output_dir, str) else output_dir
|
|
|
|
self._style = Style(
|
|
background="white",
|
|
plot_background="white",
|
|
foreground="#2c3e50",
|
|
foreground_strong="#000000",
|
|
foreground_subtle="#7f8c8d",
|
|
opacity=".9",
|
|
opacity_hover=".95",
|
|
transition="150ms ease-in",
|
|
colors=("#2ecc71", "#3498db", "#e74c3c"),
|
|
title_font_size=40,
|
|
legend_font_size=34,
|
|
label_font_size=32, #
|
|
major_label_font_size=32,
|
|
value_font_size=28,
|
|
value_label_font_size=28,
|
|
tooltip_font_size=24,
|
|
no_data_font_size=28,
|
|
font_family="Consolas, 'Courier New', monospace",
|
|
)
|
|
|
|
def generate_comparison_diagram(self, benchmark_group: BenchmarkGroupResult) -> Path:
|
|
results = benchmark_group.benchmark_results
|
|
sorted_results = sorted(results, key=lambda br: br.avg_time)
|
|
|
|
descriptions: list[str] = [br.description for br in sorted_results]
|
|
avg_times: list[float] = [br.avg_time for br in sorted_results]
|
|
median_times: list[float] = [br.median_time for br in sorted_results]
|
|
std_devs: list[float] = [br.std_dev for br in sorted_results]
|
|
|
|
max_value = max(
|
|
max(avg_times) if avg_times else 0,
|
|
max(median_times) if median_times else 0,
|
|
max(std_devs) if std_devs else 0,
|
|
)
|
|
y_limit = max_value / 0.85 if max_value > 0 else 1.0
|
|
|
|
title_text = f"{benchmark_group.type_.replace('_', ' ').title()}"
|
|
metadata_text = (
|
|
f"Iterations: {benchmark_group.iterations} | GC: "
|
|
f"{'Disabled' if benchmark_group.is_gc_disabled else 'Enabled'}"
|
|
)
|
|
|
|
filename = f"{benchmark_group.type_}_comparison.png"
|
|
output_path = self.output_dir / filename
|
|
self.output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
dynamic_height = 600 + (len(descriptions) * 150)
|
|
|
|
chart = pygal.HorizontalBar(
|
|
style=self._style,
|
|
width=3100,
|
|
height=dynamic_height,
|
|
explicit_size=True,
|
|
show_legend=True,
|
|
legend_at_bottom=True,
|
|
print_values=True,
|
|
print_values_position="top",
|
|
legend_at_bottom_columns=3,
|
|
range=(0, y_limit),
|
|
zero=0,
|
|
)
|
|
|
|
chart.title = f"{title_text}\n{metadata_text}"
|
|
chart.x_title = "Time (ms)"
|
|
chart.no_data_text = "No data"
|
|
chart.value_formatter = lambda x: f"{x:.3f}"
|
|
|
|
chart.x_labels = descriptions
|
|
|
|
chart.add("Std Deviation", std_devs)
|
|
chart.add("Average Time", avg_times)
|
|
chart.add("Median Time", median_times)
|
|
|
|
svg_bytes = chart.render()
|
|
cairosvg.svg2png(bytestring=svg_bytes, write_to=str(output_path))
|
|
|
|
return output_path
|