#!/usr/bin/env python3 -I # usage: analyse_timing.py round.csv [round2.csv ...] import csv, sys, random import numpy as np rng = np.random.default_rng(7) rows = [] for p in sys.argv[1:]: with open(p) as f: for r in csv.DictReader(f): rows.append({**r, "src": p}) def col(kind, host, key, f=lambda r: True): return [float(r[key]) for r in rows if r["kind"] == kind and r["host"] == host and f(r)] def pairs(kind, fn): d = {} for r in rows: d.setdefault((r["src"], r["iter"], r["kind"]), {})[r["host"]] = fn(r) return [(v["vercel"], v["cloudflare"]) for (s, i, k), v in d.items() if k == kind and len(v) == 2] def ci(diffs, stat=np.median, n=10000): a = np.array(diffs) boots = [stat(rng.choice(a, len(a))) for _ in range(n)] return stat(a), np.percentile(boots, 2.5), np.percentile(boots, 97.5) def q(a, p): return np.percentile(a, p) ms = lambda s: s * 1000 for kind in ("home", "post", "avif"): print(f"\n=== {kind} ===") for label, fn in (("TTFB excl DNS (P1)", lambda r: ms(float(r["ttfb"]) - float(r["dns"]))), ("TCP connect", lambda r: ms(float(r["connect"]) - float(r["dns"]))), ("TLS handshake", lambda r: ms(float(r["tls"]) - float(r["connect"]))), ("server wait (ttfb-tls)", lambda r: ms(float(r["ttfb"]) - float(r["tls"]))), ("total", lambda r: ms(float(r["total"]) - float(r["dns"])))): ps = pairs(kind, fn) if not ps: continue v = np.array([p[0] for p in ps]); c = np.array([p[1] for p in ps]) m, lo, hi = ci(v - c) print(f"{label:24s} n={len(ps):3d} vercel med {np.median(v):7.1f} p90 {q(v,90):7.1f} p99 {q(v,99):7.1f} | " f"cloudflare med {np.median(c):7.1f} p90 {q(c,90):7.1f} p99 {q(c,99):7.1f} | " f"median(V-C) {m:7.1f} [{lo:7.1f}, {hi:7.1f}] CF faster in {np.mean(v>c)*100:3.0f}% of pairs") for h in ("vercel", "cloudflare"): caches = {} for r in rows: if r["kind"] == kind and r["host"] == h: caches[r["cache"]] = caches.get(r["cache"], 0) + 1 codes = {} for r in rows: if r["kind"] == kind and r["host"] == h: codes[r["code"]] = codes.get(r["code"], 0) + 1 ips = sorted({r["ip"] for r in rows if r["kind"] == kind and r["host"] == h}) print(f" {h}: cache {caches} codes {codes} ips {len(ips)} http {sorted({r['http'] for r in rows if r['host']==h})}")