feat: harden storage, schema persistence, fair benches, fix wire crash
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
Core storage: hash MemTable, WAL group commit, L0 compaction rebuild, reader-writer lock, and a global StorageGate so HTTP workers and TCP share the LSM safely under multi-thread access. Schema: durable CREATE/ALTER/DROP under _schema:tables:* with full LSM restore on open. Executor types/values/schema split into query/exec/. Wire protocol: switch default MM to ARC — ORC cycle collector segfaulted after ~20 async INSERTs. Fair multi-tier benchmarks (SQLite/HTTP/wire/PG) and honesty docs for mixed-tier comparisons.
This commit is contained in:
@@ -1,110 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate a real comparison report from BaraDB and PostgreSQL benchmark results."""
|
||||
"""Generate benchmark reports.
|
||||
|
||||
Modes:
|
||||
python3 benchmarks/generate_report.py # legacy PG vs embedded (with warning)
|
||||
python3 benchmarks/generate_report.py --fair # multi-tier fair report from fair_bench.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
def format_ops(ops_per_sec):
|
||||
|
||||
def format_ops(ops_per_sec: float) -> str:
|
||||
if ops_per_sec >= 1_000_000:
|
||||
return f"{ops_per_sec/1_000_000:.2f}M"
|
||||
elif ops_per_sec >= 1_000:
|
||||
if ops_per_sec >= 1_000:
|
||||
return f"{ops_per_sec/1_000:.2f}K"
|
||||
else:
|
||||
return f"{ops_per_sec:.2f}"
|
||||
return f"{ops_per_sec:.2f}"
|
||||
|
||||
|
||||
def format_time(seconds):
|
||||
def format_time(seconds: float) -> str:
|
||||
if seconds < 0.001:
|
||||
return f"{seconds*1000:.3f}ms"
|
||||
elif seconds < 1:
|
||||
if seconds < 1:
|
||||
return f"{seconds*1000:.1f}ms"
|
||||
else:
|
||||
return f"{seconds:.3f}s"
|
||||
return f"{seconds:.3f}s"
|
||||
|
||||
|
||||
def main():
|
||||
root = Path(__file__).parent
|
||||
def gen_fair(out: Path) -> int:
|
||||
fair_path = ROOT / "fair_benchmark_results.json"
|
||||
if not fair_path.exists():
|
||||
print("Missing fair_benchmark_results.json — run: python3 benchmarks/fair_bench.py")
|
||||
return 1
|
||||
payload = json.loads(fair_path.read_text())
|
||||
# fair_bench already writes FAIR_COMPARISON.md; re-emit for consistency
|
||||
sys.path.insert(0, str(ROOT / "benchmarks"))
|
||||
from fair_bench import write_markdown # type: ignore
|
||||
|
||||
with open(root.parent / "benchmark_results.json") as f:
|
||||
write_markdown(payload, out)
|
||||
return 0
|
||||
|
||||
|
||||
def gen_legacy() -> int:
|
||||
"""Legacy report: PG client-server vs BaraDB *embedded* — always labeled unfair."""
|
||||
bara_path = ROOT / "benchmark_results.json"
|
||||
pg_path = ROOT / "pg_benchmark_results.json"
|
||||
if not bara_path.exists() or not pg_path.exists():
|
||||
print("Need benchmark_results.json and pg_benchmark_results.json")
|
||||
print(" nimble bench && python3 benchmarks/pg_bench.py")
|
||||
return 1
|
||||
|
||||
with open(bara_path) as f:
|
||||
bara = json.load(f)
|
||||
with open(root.parent / "pg_benchmark_results.json") as f:
|
||||
with open(pg_path) as f:
|
||||
pg = json.load(f)
|
||||
|
||||
bara_map = {r["name"]: r for r in bara["results"]}
|
||||
pg_map = {k: v for k, v in pg.items()}
|
||||
# pg_bench may write list or dict
|
||||
if isinstance(pg, dict) and "results" in pg:
|
||||
pg_map = {r["name"]: r for r in pg["results"]}
|
||||
elif isinstance(pg, list):
|
||||
pg_map = {r["name"]: r for r in pg}
|
||||
else:
|
||||
pg_map = pg # old flat dict by name
|
||||
|
||||
report = []
|
||||
report.append("# BaraDB vs PostgreSQL — Real Benchmark Results")
|
||||
report.append("# BaraDB vs PostgreSQL — LEGACY (mixed tiers)")
|
||||
report.append("")
|
||||
report.append("Generated from actual execution on:")
|
||||
report.append(f"- **CPU:** AMD Ryzen 9 5900X")
|
||||
report.append(f"- **PostgreSQL:** 15.18 (local)")
|
||||
report.append(f"- **BaraDB:** git `{bara['gitSha']}`")
|
||||
report.append("> ⚠️ **Unfair comparison warning**")
|
||||
report.append(">")
|
||||
report.append("> PostgreSQL numbers include **client-server** round-trips.")
|
||||
report.append("> BaraDB numbers are **in-process embedded** LSM (no network, no SQL).")
|
||||
report.append("> Use `python3 benchmarks/fair_bench.py` + `--fair` for honest tiers.")
|
||||
report.append("")
|
||||
report.append("## Methodology")
|
||||
report.append(f"- **BaraDB git:** `{bara.get('gitSha', 'unknown')}`")
|
||||
report.append("")
|
||||
report.append("- PostgreSQL: single-row INSERT/SELECT via psycopg2 (client-server overhead included)")
|
||||
report.append("- BaraDB: in-process Nim code (no network overhead)")
|
||||
report.append("- Same dataset sizes for both systems")
|
||||
report.append("")
|
||||
report.append("## Results")
|
||||
report.append("")
|
||||
report.append("| Test | PostgreSQL | BaraDB | Speedup |")
|
||||
report.append("|------|-----------|--------|---------|")
|
||||
report.append("| Test | PostgreSQL (C/S) | BaraDB (embedded) | Ratio (not a fair speedup) |")
|
||||
report.append("|------|------------------|-------------------|----------------------------|")
|
||||
|
||||
rows = [
|
||||
("KV Write (100K)", pg_map.get("KV Write"), bara_map.get("LSM-Write")),
|
||||
("KV Read (100K)", pg_map.get("KV Read"), bara_map.get("LSM-Read")),
|
||||
("BTree Insert (100K)", pg_map.get("BTree Insert"), bara_map.get("BTree-Insert")),
|
||||
("BTree Get (100K)", pg_map.get("BTree Get"), bara_map.get("BTree-Get")),
|
||||
("BTree Scan (1K ranges)", pg_map.get("BTree Scan"), bara_map.get("BTree-Scan")),
|
||||
("FTS Index (10K docs)", pg_map.get("FTS Index"), bara_map.get("FTS-Index")),
|
||||
("FTS Search (1K queries)", pg_map.get("FTS Search"), bara_map.get("FTS-Search")),
|
||||
("KV Write", pg_map.get("KV Write"), bara_map.get("LSM-Write")),
|
||||
("KV Read", pg_map.get("KV Read"), bara_map.get("LSM-Read")),
|
||||
("BTree Insert", pg_map.get("BTree Insert"), bara_map.get("BTree-Insert")),
|
||||
("BTree Get", pg_map.get("BTree Get"), bara_map.get("BTree-Get")),
|
||||
("BTree Scan", pg_map.get("BTree Scan"), bara_map.get("BTree-Scan")),
|
||||
("FTS Index", pg_map.get("FTS Index"), bara_map.get("FTS-Index")),
|
||||
("FTS Search", pg_map.get("FTS Search"), bara_map.get("FTS-Search")),
|
||||
]
|
||||
|
||||
total_pg_time = 0
|
||||
total_bara_time = 0
|
||||
|
||||
for name, p, b in rows:
|
||||
if p is None or b is None:
|
||||
continue
|
||||
pg_ops = p["opsPerSec"]
|
||||
ba_ops = b["opsPerSec"]
|
||||
ratio = ba_ops / pg_ops
|
||||
winner = "BaraDB" if ratio > 1 else "PostgreSQL"
|
||||
total_pg_time += p["seconds"]
|
||||
total_bara_time += b["seconds"]
|
||||
|
||||
ratio = ba_ops / pg_ops if pg_ops else 0
|
||||
report.append(
|
||||
f"| {name} | {format_ops(pg_ops)}/s ({format_time(p['seconds'])}) | "
|
||||
f"{format_ops(ba_ops)}/s ({format_time(b['seconds'])}) | "
|
||||
f"{ratio:.1f}x ({winner}) |"
|
||||
f"{ratio:.1f}x (mixed tiers) |"
|
||||
)
|
||||
|
||||
report.append("")
|
||||
report.append("## Summary")
|
||||
report.append("## Prefer fair suite")
|
||||
report.append("")
|
||||
report.append(f"- **Total PostgreSQL time:** {total_pg_time:.3f}s")
|
||||
report.append(f"- **Total BaraDB time:** {total_bara_time:.3f}s")
|
||||
overall = total_pg_time / total_bara_time
|
||||
report.append(f"- **Overall speedup:** BaraDB is **{overall:.1f}x faster**")
|
||||
report.append("")
|
||||
report.append("## Notes")
|
||||
report.append("")
|
||||
report.append("- PostgreSQL includes network round-trip and SQL parsing overhead per operation.")
|
||||
report.append("- BaraDB runs in-process with zero serialization/network cost.")
|
||||
report.append("- For embedded/single-node use cases, BaraDB shows significant advantage.")
|
||||
report.append("- PostgreSQL FTS Search with GIN index outperforms BaraDB on query throughput.")
|
||||
report.append("- PostgreSQL excels at durability, replication, and complex ACID transactions.")
|
||||
report.append("```bash")
|
||||
report.append("nim c -d:release -r benchmarks/bench_all.nim")
|
||||
report.append("python3 benchmarks/fair_bench.py")
|
||||
report.append("python3 benchmarks/generate_report.py --fair")
|
||||
report.append("```")
|
||||
report.append("")
|
||||
|
||||
output = "\n".join(report)
|
||||
print(output)
|
||||
out = ROOT / "benchmarks" / "REAL_COMPARISON.md"
|
||||
out.write_text("\n".join(report) + "\n")
|
||||
print(f"Wrote {out} (legacy mixed-tier; see warning banner)")
|
||||
return 0
|
||||
|
||||
with open(root / "REAL_COMPARISON.md", "w") as f:
|
||||
f.write(output)
|
||||
print(f"\nReport saved to {root / 'REAL_COMPARISON.md'}")
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument(
|
||||
"--fair",
|
||||
action="store_true",
|
||||
help="Emit multi-tier fair report from fair_benchmark_results.json",
|
||||
)
|
||||
ap.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
default=str(ROOT / "benchmarks" / "FAIR_COMPARISON.md"),
|
||||
help="Output path for --fair mode",
|
||||
)
|
||||
args = ap.parse_args()
|
||||
if args.fair:
|
||||
return gen_fair(Path(args.output))
|
||||
return gen_legacy()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
||||
Reference in New Issue
Block a user