@@ -61,31 +61,28 @@ See the [query definitions](graphbench/queries.py) for more details.
6161
6262### Methodology
6363
64- The benchmarks are created, so the published numbers are reproducible and hard to manipulate.
65- That's achieved by:
66-
67- - ** Engine-independent correctness oracle.** Every query is independently re-implemented in [ ` graphbench/oracle.py ` ] ( graphbench/oracle.py ) with polars
68- over the raw Parquet dataset. Each engine's result rows (over several parameter instantiations) are diffed against the oracle results; no engine,
69- including IssunDB, is ever used as the reference. Mismatches are reported, never silently omitted from timing.
70- - ** Process isolation.** Each engine is built and timed in its own worker process ([ ` graphbench/_worker.py ` ] ( graphbench/_worker.py ) ), so heap state,
71- allocator fragmentation, and caches never leak between engines, and the peak RSS reported per engine is attributable to that engine alone.
72- - ** Statistics.** Per query: a cold run (first execution after build) is reported separately; timed rounds run with the garbage collector disabled
73- until both a minimum round count and a time budget are met; the report shows median latency with a distribution-free 95% confidence interval for the
74- median (the order-statistic method, not a normal approximation on the mean), and the plot carries p25 to p75 error bars to show distribution skew.
75- - ** Honest comparisons.** Engines are labeled by kind (embedded, in-memory, and client-server) and data ingestion method; load times are never ranked
76- across kinds, the client-server network round-trip caveat is stated in every report, and Neo4j's server memory settings are recorded from the live
77- server into the results.
78- - ** Indexing differences.** Index models differ by engine and cannot be fully equalized: IssunDB auto-indexes every scalar property, Neo4j uses a
79- uniqueness index on ` id ` plus an explicit range index on the filtered column, Ladybug indexes only its primary key, and lance-graph holds no index.
80- The report spells this out so a filtered-query result is read as the engine's indexing model, not raw speed alone.
81- - ** Determinism.** The dataset is generated from a single seed, byte-for-byte reproducible, with edge rows shuffled so no engine gains a locality
82- advantage from sorted insertion order. Hardware (CPU model, cores, and RAM) is recorded in every result file.
83- - ** Scaling.** ` make sweep ` benchmarks a series of dataset scales and plots median latency vs scale per query, so results are never a single-scale
64+ To ensure reproducible, objective, and comparable performance metrics, the benchmark suite follows these practices:
65+
66+ - ** Correctness Oracle** : Every query is re-implemented in [ ` graphbench/oracle.py ` ] ( graphbench/oracle.py ) using Polars. Engine result rows are diffed
67+ against this oracle to verify correctness before timing, and mismatching queries fail validation.
68+ - ** Process Isolation** : Each engine executes queries in a dedicated worker process ([ ` graphbench/_worker.py ` ] ( graphbench/_worker.py ) ) to prevent
69+ cache, allocator, and heap contamination.
70+ - ** Statistical Rigor** : Query timing runs with the garbage collector disabled until a minimum round count and a time budget are met. Reports display
71+ the median latency, a distribution-free 95% confidence interval, and p25 to p75 error bars. Cold runs are measured and reported separately.
72+ - ** Categorization** : Engines are categorized by architecture (embedded, in-memory, or client-server) and ingestion method. Latency reports include
73+ network round-trip caveats for client-server engines and log live server settings.
74+ - ** Index Disclosure** : Engine index models are documented (such as IssunDB auto-indexing, Neo4j range indexing, LadybugDB primary key indexing, and
75+ Lance-graph no-indexing) to provide context for query latency differences.
76+ - ** Determinism** : Datasets are generated from a single seed, and edge rows are shuffled to eliminate insertion-order locality benefits. CPU, core
77+ count, and RAM specifications are saved with every run.
78+ - ** Multi-Scale Scaling** : The suite measures scaling characteristics by running a sweep across dataset sizes rather than relying on a single-point
8479 snapshot.
8580
86- Known limitations (deliberately out of scope so far): the suite measures single-threaded read-only latency; no concurrent throughput and no
87- write/update workloads. Engines may not all support every query (e.g. variable-length patterns); unsupported queries show as ` ERR ` in the report
88- rather than being dropped.
81+ #### Scope and Limitations
82+
83+ The suite currently measures single-threaded read-only latency.
84+ Concurrent throughput, write workloads, and update workloads are out of scope.
85+ Unsupported queries are reported as errors rather than being omitted.
8986
9087> [ !IMPORTANT]
9188> Benchmarking different systems (with different design philosophies, architectures, feature sets, etc.) is not straightforward and is tricky.
0 commit comments