Skip to content

Speed up matching and add matched fzf benchmarks - #56

Draft
fastducduc wants to merge 25 commits into
dangduc:mainfrom
fastducduc:codex/fzf-upstream-parity
Draft

Speed up matching and add matched fzf benchmarks#56
fastducduc wants to merge 25 commits into
dangduc:mainfrom
fastducduc:codex/fzf-upstream-parity

Conversation

@fastducduc

Copy link
Copy Markdown

Summary
Speed up ASCII, Unicode, and persistent-session matching paths.

Add a native C driver that mirrors the timed scan boundary of fzf --bench.

Publish a 19-cell matched-envelope comparison and correct the earlier cross-harness fzf ratios.

Matched-envelope result
With one worker, the candidate is 1.041x faster than pinned fzf across 19 equally weighted cells (95% bootstrap interval: 1.011x to 1.054x). It wins 11 of 19 cells and is 1.219x faster on the three real corpora.
The result is not uniform. fzf remains 1.119x faster on partial-miss cells and 1.276x faster on no-match cells. With eight workers, fzf is 1.333x faster in the equal-cell aggregate.
The candidate/base one-worker aggregate is 1.011x (interval: 0.997x to 1.018x), so the overall candidate gain is not statistically clear. The base is itself 1.037x faster than fzf in this envelope.
See benchmarks/2026-09-09T18:56:18Z.md. The correction at the top of benchmarks/2026-09-09T12:22:04Z.md marks the old cross-harness ratios as non-comparable.
Validation
760 timed fresh processes across five shuffled rounds; no outlier removal.

Candidate, base, and pinned fzf produce identical ordered output for all 19 corpora (646,229 matched lines per subject).

Full native C suite passes.

Driver passes 9,097 ASan/UBSan iterations and 9,378 TSan iterations.

Independent rebuilds match the measured binaries after removal of only the Mach-O UUID and signature regions.

Scope
This is a matched scan-boundary comparison, not identical internal work. It excludes input ingestion, query parsing, the Emacs boundary, and interactive sessions. The report documents runtime, storage, orchestration, and garbage-collection differences that can affect the result.

@fastducduc

Copy link
Copy Markdown
Author

Benchmark limitation: Skim's interactive CLI benchmark is not directly comparable with the fzf-native multi-round session measurements in this PR.

Skim's cli run target can already launch junegunn/fzf, but it measures an end-to-end envelope: process startup, pipe ingestion, initial query entry, matching, TUI rendering, and tmux status-line polling. It starts a fresh process per run and sends the complete query. The fzf-native native-session target instead loads the corpus before timing, retains one session and worker pool across query updates, and measures request submission through authoritative result publication. Comparing these elapsed times would therefore mix different work and control-plane overhead.

Related caveats:

  • Skim's internal typing Criterion case is compiled against Skim internals and sends the characters as a burst. It cannot run an arbitrary fzf binary, and it tests coalescing rather than settled prefix-by-prefix updates.
  • The CLI harness checks liveness through /proc/<pid>, so that path is currently Linux-specific and can terminate polling incorrectly on macOS.
  • Its completion check is heuristic count stability and does not validate full result order.

Recommendation: retain Skim's real-binary CLI run as a secondary end-to-end holdout only. For a primary multi-round comparison, add a benchmark-only driver in the pinned fzf package that preloads the same corpus, retains one matcher/cache, submits the identical settled query trace, times Matcher.Reset through EvtSearchFin, and validates match count plus top-K ordering outside the timed interval. A stock-fzf --sync --listen=<socket> lane can provide an additional real-process holdout, but its HTTP, JSON, terminal, and polling costs must remain separate from the matcher-session result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant