docs: update Datomic comparison after join-engine work
ober
7c45c55d0d87090b6c45bd762d9ae16b69f260cb
--- a/docs/datomic-comparison.md +++ b/docs/datomic-comparison.md @@ -18,32 +18,39 @@ selectivities are comparable. | Query | jerboa Datalog | jerboa + DuckDB | Datomic | |---|--:|--:|--:| -| **Load** (~147k entities) | **1136** | — | 1745 | +| **Load** (~147k entities) | **1011** | — | 1745 | | Q1 — artist exact name lookup | 0 | — | 0.7 | | Q2 — releases by artist name (2-hop) | 0 | — | 0.9 | | Q3 — `startYear < 1960` (range) | **1** | — | 4.8 | -| Q4 — tracks > 240s on shared-artist releases (multi-join) | 1885 | 363 | **368** | +| Q4 — tracks > 240s on shared-artist releases (multi-join) | 811 | **283** | 368 | | Q5 — releases per country (group-by) | **1** | — | 9.3 | | Q6 — reverse-ref releases for an artist | 0 | — | 0.4 | | Q7 — pull artist attributes | 0 | — | 0.0 | -| Q8 — avg track duration by release status (join + agg) | 1314 | **12** | 566 | +| Q8 — avg track duration by release status (join + agg) | **428** | 11 | 566 | + +*(jerboa Datalog figures are post-join-engine work: a per-query scan cache plus +alist bindings with O(1) extension. Before that work Q4 was 1885 ms and Q8 +1314 ms.)* ## Findings 1. **OLTP / point / index queries (Q1–Q3, Q5–Q7): jerboa is at parity or - faster.** It loads ~1.5× faster than Datomic's `mem` peer and beats it on the + faster.** It loads ~1.7× faster than Datomic's `mem` peer and beats it on the indexed scans (Q3 1 vs 5 ms, Q5 1 vs 9 ms); the rest are sub-millisecond on both. The ported index machinery — B+-tree memory index, real-cardinality planner, native group-by / pure-aggregate fast paths — holds up against Datomic. -2. **Raw Datalog multi-way joins (Q4, Q8): Datomic is faster** — ~5× on Q4 - (368 vs 1885 ms) and ~2.3× on Q8 (566 vs 1314 ms). Datomic's relational join - engine (with better join ordering) outclasses jerboa's nested-loop Datalog. - This is the real remaining engine gap. +2. **Raw Datalog multi-way joins (Q4, Q8): now close, and jerboa wins Q8.** + After the join-engine work (per-query scan cache + alist bindings), jerboa is + **faster than Datomic on Q8** (428 vs 566 ms — a join + aggregate) and the Q4 + gap shrank from ~5× to ~2.2× (811 vs 368 ms). The change that mattered was + representational: bindings are now O(1)-extend alists rather than copied + hashtables. Q4's residual gap is **result materialization** — it returns + 428k rows, where Datomic's set-of-tuples result is more compact. -3. **jerboa's DuckDB fallback erases that gap on analytics** — Q4 ties - Datomic-Datalog (363 vs 368 ms) and Q8 beats it 47× (12 vs 566 ms). +3. **jerboa's DuckDB fallback still leads on analytics** — Q4 beats + Datomic-Datalog (283 vs 368 ms) and Q8 is ~51× faster (11 vs 566 ms). ## Honest caveats @@ -62,12 +69,13 @@ selectivities are comparable. ## Net -jerboa-db is **genuinely competitive with Datomic on OLTP** at this scale, -**behind on Datalog multi-way joins** (where Datomic's engine wins 2–5×), and -**ahead on analytics only because it offloads to DuckDB** — the same strategy -Datomic uses with Presto. The gap worth closing is jerboa's Datalog join engine -(hash/merge joins, better ordering); the analytics gap is already handled by the -columnar fallback. +jerboa-db is **competitive with Datomic across the board at this scale**: faster +on load and OLTP/index queries, **faster on the Q8 join+aggregate** after the +join-engine work, and within ~2.2× on the one remaining query (Q4, a wide +428k-row result — a materialization cost, not a join-algorithm one). Its DuckDB +columnar fallback still leads on the analytical shapes, the same way Datomic +leans on Presto. The remaining lever is Q4-style result materialization +(tuple/columnar result relations); the join algorithm and analytics are handled. ## Reproduce