Skip to content

Commit

Permalink
Merge pull request #53 from josharian/optimize
Browse files Browse the repository at this point in the history
perf: avoid allocs in unicodeFoldTransformer
  • Loading branch information
lithammer authored May 3, 2023
2 parents 1174331 + 1faf692 commit 6561906
Showing 1 changed file with 14 additions and 12 deletions.
26 changes: 14 additions & 12 deletions fuzzy/fuzzy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
package fuzzy

import (
"bytes"
"unicode"
"unicode/utf8"

Expand Down Expand Up @@ -251,18 +250,21 @@ func stringTransform(s string, t transform.Transformer) (transformed string) {
type unicodeFoldTransformer struct{ transform.NopResetter }

func (unicodeFoldTransformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
runes := bytes.Runes(src)
var lowerRunes []rune
for _, r := range runes {
lowerRunes = append(lowerRunes, unicode.ToLower(r))
}

srcBytes := []byte(string(lowerRunes))
n := copy(dst, srcBytes)
if n < len(srcBytes) {
err = transform.ErrShortDst
n := 0
// Converting src to a string allocates.
// In theory, it need not; see https://go.dev/issue/27148.
// It is possible to write this loop using utf8.DecodeRune
// and thereby avoid allocations, but it is noticeably slower.
// So just let's wait for the compiler to get smarter.
for _, r := range string(src) {
r = unicode.ToLower(r)
x := utf8.RuneLen(r)
if x > len(dst[n:]) {
err = transform.ErrShortDst
break
}
n += utf8.EncodeRune(dst[n:], r)
}

return n, n, err
}

Expand Down

0 comments on commit 6561906

Please sign in to comment.