aboutsummaryrefslogtreecommitdiff
path: root/src/unicode
diff options
context:
space:
mode:
authorMartin Möhrmann <moehrmann@google.com>2018-04-24 15:13:08 +0200
committerMartin Möhrmann <moehrmann@google.com>2018-05-06 05:31:01 +0000
commitb9a59d9f2e78ce497b38a984f62094a53e7dfce7 (patch)
treec595460f4950f5f76d59cec82c651993ea449196 /src/unicode
parenta8a60ac2a7bec701de6b502889e1dc740761e183 (diff)
downloadgo-b9a59d9f2e78ce497b38a984f62094a53e7dfce7.tar.gz
go-b9a59d9f2e78ce497b38a984f62094a53e7dfce7.zip
cmd/compile: optimize len([]rune(string))
Adds a new runtime function to count runes in a string. Modifies the compiler to detect the pattern len([]rune(string)) and replaces it with the new rune counting runtime function. RuneCount/lenruneslice/ASCII 27.8ns ± 2% 14.5ns ± 3% -47.70% (p=0.000 n=10+10) RuneCount/lenruneslice/Japanese 126ns ± 2% 60ns ± 2% -52.03% (p=0.000 n=10+10) RuneCount/lenruneslice/MixedLength 104ns ± 2% 50ns ± 1% -51.71% (p=0.000 n=10+9) Fixes #24923 Change-Id: Ie9c7e7391a4e2cca675c5cdcc1e5ce7d523948b9 Reviewed-on: https://go-review.googlesource.com/108985 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Diffstat (limited to 'src/unicode')
-rw-r--r--src/unicode/utf8/utf8_test.go21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/unicode/utf8/utf8_test.go b/src/unicode/utf8/utf8_test.go
index dc9c4251bd..359461bd05 100644
--- a/src/unicode/utf8/utf8_test.go
+++ b/src/unicode/utf8/utf8_test.go
@@ -212,14 +212,25 @@ func TestSequencing(t *testing.T) {
}
}
-// Check that a range loop and a []int conversion visit the same runes.
+func runtimeRuneCount(s string) int {
+ return len([]rune(s)) // Replaced by gc with call to runtime.countrunes(s).
+}
+
+// Check that a range loop, len([]rune(string)) optimization and
+// []rune conversions visit the same runes.
// Not really a test of this package, but the assumption is used here and
-// it's good to verify
-func TestIntConversion(t *testing.T) {
+// it's good to verify.
+func TestRuntimeConversion(t *testing.T) {
for _, ts := range testStrings {
+ count := RuneCountInString(ts)
+ if n := runtimeRuneCount(ts); n != count {
+ t.Errorf("%q: len([]rune()) counted %d runes; got %d from RuneCountInString", ts, n, count)
+ break
+ }
+
runes := []rune(ts)
- if RuneCountInString(ts) != len(runes) {
- t.Errorf("%q: expected %d runes; got %d", ts, len(runes), RuneCountInString(ts))
+ if n := len(runes); n != count {
+ t.Errorf("%q: []rune() has length %d; got %d from RuneCountInString", ts, n, count)
break
}
i := 0