-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Open
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performance
Milestone
Description
Code like the following is unfortunately very common:
r, n := rune(b[0]), 1
if r >= utf8.RuneSelf {
r, n = utf8.DecodeRune(b)
}
and we have several examples in the standard library itself:
- fmt/format.go:347
- fmt/print.go:1101
- regexp/regexp.go:418
- regexp/regexp.go:465
- bytes/bytes.go:482
- bytes/bytes.go:560
- bytes/bytes.go:781
- bytes/bytes.go:836
- bufio/bufio.go:295
- strings/strings.go:741
- strconv/quote.go:43
- strconv/quote.go:266
All of these cases ultimate come down to the caller manually performing inlined logic for the ASCII case. We should make it such that DecodeRune
and DecodeLastRune
are inlineable for the ASCII case. Unfortunately my attempts to do so exceed the inline budget by ever so much:
// cannot inline DecodeRune: function too complex: cost 87 exceeds budget 80
func DecodeRune(p []byte) (r rune, size int) {
if len(p) > 0 && p[0] < RuneSelf {
return rune(p[0]), 1
}
return decodeRune(p)
}
// cannot inline DecodeLastRune: function too complex: cost 93 exceeds budget 80
func DecodeLastRune(p []byte) (r rune, size int) {
if len(p) > 0 && p[len(p)-1] < UTFMax {
return rune(p[len(p)-1]), 1
}
return decodeLastRune(p)
}
We should find a way to make these inlinable whether by special casing them, clever tricks to make the cost lower, by increasing the inline budget, etc.
josharian, CAFxX, renthraysk, mvdan, mengzhuo and 2 more
Metadata
Metadata
Assignees
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performance