Skip to content

unicode/utf8: make DecodeRune and DecodeLastRune inlineable #48195

@dsnet

Description

@dsnet

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:

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.

\cc @CAFxX @josharian @mdempsky @martisch

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performance

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions