Skip to main content

Benchmarks

Differens compares code structurally instead of line by line. Parsing and matching cost more than git 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

Measured on an M-series MacBook with bun run apps/cli/bench/bench.ts. Each case runs end to end: parse, match, narrate. Matching is linear in node count: top-down anchors, bottom-up containers, leaf recovery, all over flat typed arrays. There is no node-count cap and no file-size cap: every input is matched for real. Large text files use a linear-space Myers diff, so a one-line edit in a 100k-line file costs ~9 ms instead of degrading to a whole-file update. Two caches keep repeat work off the hot path. A content-addressed parse cache (64-entry LRU, keyed by content hash and extension) reuses the parse tree whenever the same file content reappears in a run. Repeated identical content short-circuits before any parsing at all.

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, large text files (linear-space Myers), fully rewritten files (one Update), repeat content within a run (parse cache).
  • Slow: the first parse of a huge file on a cold grammar cache; binary comparisons (hash only, so rarely worth it).
  • Noted, not needed yet: a persistent cross-run parse cache, SSE output (ndjson covers streaming already).