mirror of
https://github.com/junegunn/fzf
synced 2026-08-08 19:41:43 +00:00
Skip rune decoding for ASCII bytes in ToChars
utf8.DecodeRune already fast-paths ASCII, but it is too complex to inline (cost 201 against a budget of 80), so a mostly-ASCII line pays one call per byte just to be told the byte is ASCII. Only the run after the first non-ASCII byte reaches the decode loop, so the gain depends on where that byte falls. - 70-rune ASCII line: 145ns -> 42ns in the decode loop - Ingestion of 1.4M mostly-ASCII paths behind a Hangul prefix, where the loop covers the whole line: 377ms -> 233ms - The same paths with the Hangul at the end, where it covers six bytes: 207ms -> 196ms - Break-even sits at ~100% non-ASCII runes: still 1.01x at 95%. Only a line holding no ASCII byte at all loses, by ~0.14ns per rune, ~5% of the loop
This commit is contained in:
@@ -77,6 +77,13 @@ func ToChars(bytes []byte) Chars {
|
||||
runes[i] = rune(bytes[i])
|
||||
}
|
||||
for i := bytesUntil; i < len(bytes); {
|
||||
// utf8.DecodeRune has an ASCII path of its own, but it is too complex
|
||||
// to inline, so a mostly-ASCII line pays one call per byte for it.
|
||||
if b := bytes[i]; b < utf8.RuneSelf {
|
||||
runes = append(runes, rune(b))
|
||||
i++
|
||||
continue
|
||||
}
|
||||
r, sz := utf8.DecodeRune(bytes[i:])
|
||||
i += sz
|
||||
runes = append(runes, r)
|
||||
|
||||
Reference in New Issue
Block a user