diff --git a/CHANGELOG.md b/CHANGELOG.md index ec1a4693..52e2af48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/result.go b/src/result.go index 77db9397..bcc5d84b 100644 --- a/src/result.go +++ b/src/result.go @@ -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)]++