Skip to content

Commit f04ab10

Browse files
author
Alexandra Pavlyshina
committed
measure_perf: switch from cohort to aggregate SQL
1 parent 56e379e commit f04ab10

1 file changed

Lines changed: 24 additions & 18 deletions

File tree

aidbox-custom-operations/measure-evaluate/tools/measure_perf.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#!/usr/bin/env python3
2-
"""Cohort SQL perf benchmark for 12 measures on AME Aidbox.
2+
"""Aggregate SQL perf benchmark for 12 measures on AME Aidbox.
33
4-
Mirrors aidbox-cql-poc/experiments/dba-optimization/measure_perf.py, but reads
5-
measure SQL from this repo's sql/measures/cmsXXX/02-cmsXXX-measure.sql layout
6-
and targets the AME Aidbox at http://localhost:8888 by default.
4+
Runs each measure's aggregate SQL (SELECT COUNT(*) ...) — the same query
5+
that $evaluate-measure summary mode executes in production.
76
87
Usage:
98
python3 tools/measure_perf.py --label before
@@ -42,48 +41,55 @@ def run_sql(query: str, base_url: str, user: str, password: str, timeout: int =
4241
return json.loads(resp.read())
4342

4443

45-
def build_cohort_sql(measure_id: str) -> str:
44+
def build_aggregate_sql(measure_id: str) -> str:
45+
"""Return aggregate SQL that matches what $evaluate-measure summary mode runs."""
46+
# CMS165: PL/pgSQL wrapper with SET LOCAL enable_nestloop = off
47+
if measure_id == "cms165":
48+
return (f"SELECT * FROM cms165_aggregate("
49+
f"'{PERIOD_START}T00:00:00Z'::timestamptz,"
50+
f"'{PERIOD_END}T23:59:59Z'::timestamptz)")
51+
# All others: raw aggregate SQL from file (SELECT COUNT(*) ...)
4652
sql_path = ROOT / "sql" / "measures" / measure_id / f"02-{measure_id}-measure.sql"
4753
sql = sql_path.read_text()
48-
sql = em.parameterize_sql(sql, PERIOD_START, PERIOD_END)
49-
return em.build_patient_sql(sql, None)
54+
return em.parameterize_sql(sql, PERIOD_START, PERIOD_END)
5055

5156

5257
def measure_one(measure_id: str, base_url: str, user: str, password: str,
5358
warm: bool = True, iterations: int = 1) -> dict:
54-
"""Run cohort SQL `iterations` times after one warmup. Report median+min+max."""
55-
cohort_sql = build_cohort_sql(measure_id)
59+
"""Run aggregate SQL `iterations` times after one warmup. Report median+min+max."""
60+
sql = build_aggregate_sql(measure_id)
5661
if warm:
5762
try:
58-
run_sql(cohort_sql, base_url, user, password)
63+
run_sql(sql, base_url, user, password)
5964
except Exception as e:
6065
return {"error": f"warmup failed: {e}"}
6166
samples: list[float] = []
6267
last_rows = None
6368
for _ in range(iterations):
6469
t0 = time.time()
6570
try:
66-
rows = run_sql(cohort_sql, base_url, user, password)
71+
rows = run_sql(sql, base_url, user, password)
6772
except urllib.error.HTTPError as e:
6873
return {"error": f"HTTP {e.code}: {e.read()[:200].decode(errors='replace')}"}
6974
except Exception as e:
7075
return {"error": str(e)[:200]}
7176
samples.append((time.time() - t0) * 1000)
7277
last_rows = rows
7378
rows = last_rows or []
74-
n_rows = len(rows) if isinstance(rows, list) else 0
75-
n_ip = sum(1 for r in rows if r.get("ip"))
76-
n_den = sum(1 for r in rows if r.get("den"))
77-
n_exc = sum(1 for r in rows if r.get("exc"))
78-
n_num = sum(1 for r in rows if r.get("num"))
79+
80+
r = rows[0] if rows else {}
81+
n_ip = r.get("initial_population", 0)
82+
n_den = r.get("denominator", 0)
83+
n_exc = r.get("denominator_exclusion", 0) or 0
84+
n_num = r.get("numerator", 0) or 0
85+
7986
samples.sort()
8087
median = samples[len(samples) // 2]
8188
return {
8289
"samples_ms": [round(s, 1) for s in samples],
8390
"median_ms": round(median, 1),
8491
"min_ms": round(min(samples), 1),
8592
"max_ms": round(max(samples), 1),
86-
"rows": n_rows,
8793
"ip": n_ip, "den": n_den, "exc": n_exc, "num": n_num,
8894
}
8995

@@ -117,7 +123,7 @@ def main():
117123
print(f" ERROR: {result['error']}")
118124
else:
119125
spread = f"({result['min_ms']:.0f}{result['max_ms']:.0f})"
120-
print(f" median={result['median_ms']:>7.1f}ms {spread:>14s} rows={result['rows']:6d} "
126+
print(f" median={result['median_ms']:>7.1f}ms {spread:>14s} "
121127
f"ip={result['ip']}/den={result['den']}/exc={result['exc']}/num={result['num']}")
122128

123129
out_path = OUT_DIR / f"perf-{args.label}.json"

0 commit comments

Comments
 (0)