aboutsummaryrefslogtreecommitdiffstats
path: root/research/experiments/030-app-lifecycle/pairs.py
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-04 11:07:55 +0100
committereunhhu <[email protected]>2026-10-04 11:07:55 +0100
commit52e51e4231f2e119c97826ae6d6e2f2af0da0c58 (patch)
tree0f17ced79a1881bd2b67fbaa9e7ffb823f54b984 /research/experiments/030-app-lifecycle/pairs.py
parent420b749742badd26daf2474e9f157af17be2907f (diff)
downloadpure-52e51e4231f2e119c97826ae6d6e2f2af0da0c58.tar.gz
pure-52e51e4231f2e119c97826ae6d6e2f2af0da0c58.zip
Say what apps that change on a running host showed (017 stage 3, research 115)
Changing an app in place keeps a million items' app answering but for 1.12 ms (a host restart: 150 ms; stopping and starting it again from its store, as first built, 150.4 ms), 171.5 ms when its records change shape (332 ms). Another app's p99 stays 0.97 times as it was while one changes every 0.2 s; a host of one app is as it was (TPC-C +0.7%, instructions at most +0.02%); each module change leaves 19 KB. 030 holds the windows of both builds, the isolation, the pairs, the counts and the memory.
Diffstat (limited to 'research/experiments/030-app-lifecycle/pairs.py')
-rw-r--r--research/experiments/030-app-lifecycle/pairs.py45
1 files changed, 45 insertions, 0 deletions
diff --git a/research/experiments/030-app-lifecycle/pairs.py b/research/experiments/030-app-lifecycle/pairs.py
new file mode 100644
index 0000000..2ea4f48
--- /dev/null
+++ b/research/experiments/030-app-lifecycle/pairs.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+"""The pairs of runs.sh pairs as a table (research 115): each round's TPC-C
+(transactions a second, CPU a transaction, the owner's core share) before
+and after, the medians and the bank queries' median times.
+
+pairs.py DATE from DATE-tpcc-*.jsonl and DATE-queries-*.jsonl beside it
+"""
+import json
+import statistics
+import sys
+from pathlib import Path
+
+HERE = Path(__file__).resolve().parent
+day = sys.argv[1]
+
+
+def tpcc(version, round_):
+ for line in (HERE / f'{day}-tpcc-{version}-{round_}.jsonl').read_text().splitlines():
+ r = json.loads(line)
+ if r.get('step') == 'run' and r.get('system') == 'pure':
+ owner = max((share for name, share in r['core_shares'].items() if 'owner' in name), default=None) \
+ if isinstance(r['core_shares'], dict) else None
+ return r['transactions_per_second'], r['cpu_us_per_transaction'], owner
+
+
+def queries(version, round_):
+ return {r['query']: r['pure_median_ms'] for r in map(json.loads, (HERE / f'{day}-queries-{version}-{round_}.jsonl')
+ .read_text().splitlines()) if 'query' in r}
+
+
+rounds = sorted({int(p.stem.rsplit('-', 1)[1]) for p in HERE.glob(f'{day}-tpcc-before-*.jsonl')})
+rows = {'before': [], 'in-place': []}
+for round_ in rounds:
+ b, a = tpcc('before', round_), tpcc('in-place', round_)
+ rows['before'].append(b), rows['in-place'].append(a)
+ print(json.dumps({'round': round_, 'tps': [b[0], a[0]], 'change': round((a[0] / b[0] - 1) * 100, 1),
+ 'cpu_us': [b[1], a[1]], 'owner_share': [b[2], a[2]]}))
+med = {v: statistics.median(t for t, _, _ in rows[v]) for v in rows}
+cpu = {v: statistics.median(c for _, c, _ in rows[v]) for v in rows}
+names = queries('before', rounds[0]).keys()
+q = {v: {n: statistics.median(queries(v, r)[n] for r in rounds) for n in names} for v in rows}
+print(json.dumps({'tps_median': [med['before'], med['in-place']], 'change': round((med['in-place'] / med['before'] - 1) * 100, 1),
+ 'cpu_us_median': [cpu['before'], cpu['in-place']],
+ 'queries_median_ms': {n: [q['before'][n], q['in-place'][n],
+ round((q['in-place'][n] / q['before'][n] - 1) * 100, 1)] for n in names}}))