Skip to content

Commit

Permalink
bytes, strings: restore O(1) behavior of IndexAny(s, "") and LastInde…
Browse files Browse the repository at this point in the history
…xAny(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 <rsc@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
  • Loading branch information
rsc committed Nov 15, 2017
1 parent e7628be commit 2a166c9
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/bytes/bytes.go
Expand Up @@ -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 {
Expand Down Expand Up @@ -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-- {
Expand Down
2 changes: 1 addition & 1 deletion src/bytes/example_test.go
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/strings/strings.go
Expand Up @@ -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++ {
Expand All @@ -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-- {
Expand Down

0 comments on commit 2a166c9

Please sign in to comment.