Skip all-zero passes in radix sort of results

Precompute OR of all sort keys; a byte position that is zero across every
key contributes a no-op pass. Default two-criteria setup leaves the low 32
bits zero, so 4 of 8 passes are skipped without a histogram scan. 2x on the
sort, 3-8% on high-match queries. No regression when all bytes are used.
This commit is contained in:
Junegunn Choi
2026-07-24 16:29:47 +09:00
parent 2209a94e13
commit 0efef298d2
2 changed files with 14 additions and 1 deletions
+2 -1
View File
@@ -3,8 +3,9 @@ CHANGELOG
0.74.2
------
- Up to 2x faster matching for single-character queries
- Single-character queries are up to 2.4x faster
- This is the most latency-sensitive case; the first keystroke scans the entire list before the result cache can help
- Faster sorting of search results; the default two-criteria ranking skips redundant radix passes
- Fixed nondeterministic match highlight positions
- fzf now detects terminal resize on Windows in `--height` mode (#4790) (@Cyrus580529)
- Fixed signal handler cleanup when fzf is used as a library; SIGINT/SIGTERM/SIGHUP and resize handlers no longer persist after `Run()` returns
+12
View File
@@ -369,9 +369,21 @@ func radixSortResults(a []Result, tac bool, scratch []Result) []Result {
src, dst := a, buf
scattered := 0
// OR of all keys: a byte position that is zero here is zero in every key,
// so its pass is a no-op and can be skipped without a histogram scan.
// With the common two-criteria setup the low 32 bits are always zero.
var keyOR uint64
for i := range src {
keyOR |= sortKey(&src[i])
}
for pass := range 8 {
shift := uint(pass) * 8
if byte(keyOR>>shift) == 0 {
continue
}
var count [256]int
for i := range src {
count[byte(sortKey(&src[i])>>shift)]++