From: Russ Cox Date: Tue, 14 Nov 2017 02:30:22 +0000 (-0500) Subject: bytes, strings: restore O(1) behavior of IndexAny(s, "") and LastIndexAny(s, "") X-Git-Tag: go1.10beta1~261 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2a166c93a3d2a7ba73e129649b7b41b6c696e74a;p=gostls13.git bytes, strings: restore O(1) behavior of IndexAny(s, "") and LastIndexAny(s, "") CL 65851 (bytes) and CL 65910 (strings) “improve[d] readability” by removing the special case that bypassed the whole function body when chars == "". In doing so, yes, the function was unindented a level, which is nice, but the runtime of that case went from O(1) to O(n) where n = len(s). I don't know if anyone's code depends on the O(1) behavior in this case, but quite possibly someone's does. This CL adds the special case back, with a comment to prevent future deletions, and without reindenting each function body in full. Change-Id: I5aba33922b304dd1b8657e6d51d6c937a7f95c81 Reviewed-on: https://go-review.googlesource.com/78112 Run-TryBot: Russ Cox Reviewed-by: Brad Fitzpatrick --- diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go index 260f32500a..9af177fa88 100644 --- a/src/bytes/bytes.go +++ b/src/bytes/bytes.go @@ -144,6 +144,10 @@ func IndexRune(s []byte, r rune) int { // code points in chars. It returns -1 if chars is empty or if there is no code // point in common. func IndexAny(s []byte, chars string) int { + if chars == "" { + // Avoid scanning all of s. + return -1 + } if len(s) > 8 { if as, isASCII := makeASCIISet(chars); isASCII { for i, c := range s { @@ -176,6 +180,10 @@ func IndexAny(s []byte, chars string) int { // the Unicode code points in chars. It returns -1 if chars is empty or if // there is no code point in common. func LastIndexAny(s []byte, chars string) int { + if chars == "" { + // Avoid scanning all of s. + return -1 + } if len(s) > 8 { if as, isASCII := makeASCIISet(chars); isASCII { for i := len(s) - 1; i >= 0; i-- { diff --git a/src/bytes/example_test.go b/src/bytes/example_test.go index 00e39cadcb..5b7a46058f 100644 --- a/src/bytes/example_test.go +++ b/src/bytes/example_test.go @@ -155,7 +155,7 @@ func ExampleCount() { func ExampleEqual() { fmt.Println(bytes.Equal([]byte("Go"), []byte("Go"))) - fmt.Println(bytes.Equal([]byte("Go"), []byte("go"))) + fmt.Println(bytes.Equal([]byte("Go"), []byte("C++"))) // Output: // true // false diff --git a/src/strings/strings.go b/src/strings/strings.go index c66c248c02..02c032046b 100644 --- a/src/strings/strings.go +++ b/src/strings/strings.go @@ -166,6 +166,10 @@ func IndexRune(s string, r rune) int { // IndexAny returns the index of the first instance of any Unicode code point // from chars in s, or -1 if no Unicode code point from chars is present in s. func IndexAny(s, chars string) int { + if chars == "" { + // Avoid scanning all of s. + return -1 + } if len(s) > 8 { if as, isASCII := makeASCIISet(chars); isASCII { for i := 0; i < len(s); i++ { @@ -190,6 +194,10 @@ func IndexAny(s, chars string) int { // point from chars in s, or -1 if no Unicode code point from chars is // present in s. func LastIndexAny(s, chars string) int { + if chars == "" { + // Avoid scanning all of s. + return -1 + } if len(s) > 8 { if as, isASCII := makeASCIISet(chars); isASCII { for i := len(s) - 1; i >= 0; i-- {