mirror of
https://github.com/status-im/nimbus-eth1-benchmarks.git
synced 2026-08-27 06:41:15 +00:00
119 lines
3.4 KiB
Python
119 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate simple benchmark trend graph from CSV data."""
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.axes import Axes
|
|
import pandas as pd
|
|
from scipy.ndimage import uniform_filter1d
|
|
|
|
|
|
def parse_duration_to_hours(duration_str: str) -> Optional[float]:
|
|
"""Convert duration string like '8h6m44s' to hours as float."""
|
|
if not duration_str or pd.isna(duration_str):
|
|
return None
|
|
|
|
hours = 0
|
|
minutes = 0
|
|
seconds = 0
|
|
|
|
h_match = re.search(r'(\d+)h', duration_str)
|
|
if h_match:
|
|
hours = int(h_match.group(1))
|
|
|
|
m_match = re.search(r'(\d+)m', duration_str)
|
|
if m_match:
|
|
minutes = int(m_match.group(1))
|
|
|
|
s_match = re.search(r'(\d+)s', duration_str)
|
|
if s_match:
|
|
seconds = int(s_match.group(1))
|
|
|
|
return hours + minutes / 60 + seconds / 3600
|
|
|
|
|
|
def load_data(csv_path: Path) -> pd.DataFrame:
|
|
"""Load CSV and prepare data for plotting."""
|
|
df = pd.read_csv(csv_path)
|
|
df['Date'] = pd.to_datetime(df['Generated At'])
|
|
df['Hours'] = df['Contender Time'].apply(parse_duration_to_hours)
|
|
df = df.sort_values('Date').reset_index(drop=True)
|
|
return df.dropna(subset=['Hours'])
|
|
|
|
|
|
def set_commit_sha_xticks(ax: Axes, df: pd.DataFrame, max_labels: int = 15) -> None:
|
|
"""Label x-axis ticks with short commit SHAs at evenly-spaced intervals."""
|
|
n = len(df)
|
|
step = max(1, n // max_labels)
|
|
positions = list(range(0, n, step))
|
|
labels = [df['Contender SHA'].iloc[i][:8] for i in positions]
|
|
ax.set_xticks(positions)
|
|
ax.set_xticklabels(labels, rotation=45, ha='right', fontsize=7)
|
|
|
|
|
|
def generate_trend_graph(
|
|
short_df: pd.DataFrame,
|
|
long_df: pd.DataFrame,
|
|
output_path: Path
|
|
) -> None:
|
|
"""Generate simple performance trend graph."""
|
|
_, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 6))
|
|
|
|
# Short benchmarks
|
|
if len(short_df) >= 7:
|
|
smoothed = uniform_filter1d(short_df['Hours'].values, size=7)
|
|
ax1.plot(range(len(short_df)), smoothed, 'b-', linewidth=2)
|
|
|
|
ax1.set_ylabel('Hours')
|
|
ax1.set_title('Short Benchmark (24h run) - lower is better')
|
|
ax1.grid(True, alpha=0.3)
|
|
set_commit_sha_xticks(ax1, short_df)
|
|
|
|
# Long benchmarks
|
|
if len(long_df) >= 3:
|
|
smoothed = uniform_filter1d(long_df['Hours'].values, size=3)
|
|
ax2.plot(range(len(long_df)), smoothed, 'g-', linewidth=2)
|
|
|
|
ax2.set_ylabel('Hours')
|
|
ax2.set_title('Long Benchmark (1 week run) - lower is better')
|
|
ax2.grid(True, alpha=0.3)
|
|
set_commit_sha_xticks(ax2, long_df)
|
|
|
|
plt.tight_layout()
|
|
plt.savefig(output_path, dpi=150, bbox_inches='tight')
|
|
plt.close()
|
|
print(f"Generated: {output_path}")
|
|
|
|
|
|
def main() -> int:
|
|
"""Main entry point."""
|
|
script_dir = Path(__file__).parent
|
|
assets_dir = script_dir / 'assets'
|
|
assets_dir.mkdir(exist_ok=True)
|
|
|
|
short_csv = script_dir / 'short-benchmark-history.csv'
|
|
long_csv = script_dir / 'long-benchmark-history.csv'
|
|
|
|
if not short_csv.exists() or not long_csv.exists():
|
|
print("Error: CSV files not found. Run regenerate_readme.sh first.")
|
|
return 1
|
|
|
|
short_df = load_data(short_csv)
|
|
long_df = load_data(long_csv)
|
|
|
|
print(f"Loaded {len(short_df)} short benchmark entries")
|
|
print(f"Loaded {len(long_df)} long benchmark entries")
|
|
|
|
generate_trend_graph(short_df, long_df, assets_dir / 'benchmark-trend.png')
|
|
|
|
print("Done!")
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|