#!/usr/bin/env python3 """Parse Perf lines from a log file and plot sample mean, write mean, and loop mean over time.""" import sys import re import os from datetime import datetime import matplotlib.pyplot as plt PERF_RE = re.compile( r"^(\w+ \d+ \d+:\d+:\d+) .* Perf\(.*?\):" r".*?sample mean=([\d.]+)ms" r".*?write mean=([\d.]+)ms" r".*?loop mean=([\d.]+)ms" ) def parse_log(log_path): timestamps = [] sample_means = [] write_means = [] loop_means = [] with open(log_path, "r") as f: for line in f: m = PERF_RE.search(line) if m: ts_str, sample, write, loop = m.groups() ts = datetime.strptime(ts_str, "%b %d %H:%M:%S") timestamps.append(ts) sample_means.append(float(sample)) write_means.append(float(write)) loop_means.append(float(loop)) if not timestamps: print("No Perf lines found in the log file.", file=sys.stderr) sys.exit(1) t0 = timestamps[0] seconds = [(t - t0).total_seconds() for t in timestamps] return seconds, sample_means, write_means, loop_means def plot(seconds, sample_means, write_means, loop_means, out_path): plt.figure(figsize=(12, 6)) plt.plot(seconds, sample_means, label="sample mean (ms)") plt.plot(seconds, write_means, label="write mean (ms)") plt.plot(seconds, loop_means, label="loop mean (ms)") plt.xlabel("Time (s)") plt.ylabel("Duration (ms)") plt.title("Perf Metrics Over Time") plt.legend() plt.grid(True) plt.tight_layout() plt.savefig(out_path, dpi=150) print(f"Plot saved to {out_path}") def main(): if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} ", file=sys.stderr) sys.exit(1) log_path = sys.argv[1] if not os.path.isfile(log_path): print(f"File not found: {log_path}", file=sys.stderr) sys.exit(1) seconds, sample_means, write_means, loop_means = parse_log(log_path) log_dir = os.path.dirname(os.path.abspath(log_path)) log_base = os.path.splitext(os.path.basename(log_path))[0] out_path = os.path.join(log_dir, f"{log_base}_perf_plot.png") plot(seconds, sample_means, write_means, loop_means, out_path) if __name__ == "__main__": main()