Benchmarks
Differens compares code structurally instead of line by line. Parsing and matching cost more thangit diff’s instant line comparison, but matching is fast: a single linear pass. In return, it reports “renamed” and “moved” where git diff shows a delete/insert pair.
Typical numbers
Matching is linear in node count: top-down anchors, bottom-up containers, leaf recovery. The worst-case bottom-up bound is quadratic in container pairs. That is why the engine has a
maxNodes valve: trees above the limit fall back to a line diff instead of risking a slow match.
The valve defaults to 250,000 nodes. It was raised from the original 50,000 once matching became linear. The old ceiling was sending ordinary large files to line diffing for no reason. The current limit is about memory, not time. It is configurable per call via MatchOptions.maxNodes.
How to run benchmarks
The benchmark harness lives in the CLI package and is run with Bun:Compared to git diff
For line-level changes on unparseable files, both engines use the same algorithm: a line diff. Differens is the same order of speed.
Fast, slow, being worked on
- Fast: structural matching on code and data files, whole-file adds/removals (one action, no tree), same-file moves, batched blob reads.
- Slow: the first parse of a huge file on a cold cache; enormous trees that trip the
maxNodesvalve and fall back to lines; very large binary comparisons (hash only, so rarely worth it). - Being worked on: streaming ndjson output for long changesets, incremental matching across repeated runs, and faster prose/word diffing on big documents.