aboutsummaryrefslogtreecommitdiff
path: root/src/unicode
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2019-04-24 15:31:24 -0700
committerJosh Bleecher Snyder <josharian@gmail.com>2019-04-25 00:01:23 +0000
commit7596ad0b24436dcde6a370139fbac34a95f15923 (patch)
tree3ce52745b785cd45c9bb3cea6cea80f703ed346a /src/unicode
parent2be64d36456d6e2ad14476b6d09b9fc4e2ac591e (diff)
downloadgo-7596ad0b24436dcde6a370139fbac34a95f15923.tar.xz
unicode/utf8: remove some bounds checks from DecodeRune
The compiler couldn't quite see that reading p[2] and p[3] was safe. This change provides a few hints to help it. First, make sz an int throughout, rather than just when checking the input length. Second, use <= instead of == in later comparisons. name old time/op new time/op delta DecodeASCIIRune-8 2.62ns ± 3% 2.60ns ± 5% ~ (p=0.126 n=18+19) DecodeJapaneseRune-8 4.46ns ±10% 4.01ns ± 5% -10.00% (p=0.000 n=19+20) Change-Id: I2f78a17e38156fbf8b0f5dd6c07c20d6a47e9209 Reviewed-on: https://go-review.googlesource.com/c/go/+/173662 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/unicode')
-rw-r--r--src/unicode/utf8/utf8.go16
1 files changed, 8 insertions, 8 deletions
diff --git a/src/unicode/utf8/utf8.go b/src/unicode/utf8/utf8.go
index 2d4a486256..eae4ead0da 100644
--- a/src/unicode/utf8/utf8.go
+++ b/src/unicode/utf8/utf8.go
@@ -161,23 +161,23 @@ func DecodeRune(p []byte) (r rune, size int) {
mask := rune(x) << 31 >> 31 // Create 0x0000 or 0xFFFF.
return rune(p[0])&^mask | RuneError&mask, 1
}
- sz := x & 7
+ sz := int(x & 7)
accept := acceptRanges[x>>4]
- if n < int(sz) {
+ if n < sz {
return RuneError, 1
}
b1 := p[1]
if b1 < accept.lo || accept.hi < b1 {
return RuneError, 1
}
- if sz == 2 {
+ if sz <= 2 { // <= instead of == to help the compiler eliminate some bounds checks
return rune(p0&mask2)<<6 | rune(b1&maskx), 2
}
b2 := p[2]
if b2 < locb || hicb < b2 {
return RuneError, 1
}
- if sz == 3 {
+ if sz <= 3 {
return rune(p0&mask3)<<12 | rune(b1&maskx)<<6 | rune(b2&maskx), 3
}
b3 := p[3]
@@ -209,23 +209,23 @@ func DecodeRuneInString(s string) (r rune, size int) {
mask := rune(x) << 31 >> 31 // Create 0x0000 or 0xFFFF.
return rune(s[0])&^mask | RuneError&mask, 1
}
- sz := x & 7
+ sz := int(x & 7)
accept := acceptRanges[x>>4]
- if n < int(sz) {
+ if n < sz {
return RuneError, 1
}
s1 := s[1]
if s1 < accept.lo || accept.hi < s1 {
return RuneError, 1
}
- if sz == 2 {
+ if sz <= 2 { // <= instead of == to help the compiler eliminate some bounds checks
return rune(s0&mask2)<<6 | rune(s1&maskx), 2
}
s2 := s[2]
if s2 < locb || hicb < s2 {
return RuneError, 1
}
- if sz == 3 {
+ if sz <= 3 {
return rune(s0&mask3)<<12 | rune(s1&maskx)<<6 | rune(s2&maskx), 3
}
s3 := s[3]