diff options
author | Josh Bleecher Snyder <josharian@gmail.com> | 2017-12-18 10:53:55 -0800 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2018-02-13 18:44:40 +0000 |
commit | df5997b99b9a89e1198596366230fa6c4dd50b70 (patch) | |
tree | e52ebadceac886d89e1debc251f3eeca21a2816c /src/regexp | |
parent | 4b8a7eafef039af1834ef9bfa879257c4a72b7b5 (diff) | |
download | go-df5997b99b9a89e1198596366230fa6c4dd50b70.tar.gz go-df5997b99b9a89e1198596366230fa6c4dd50b70.zip |
regexp: don't allocate when All methods find no matches
name old time/op new time/op delta
FindAllNoMatches-8 216ns ± 3% 122ns ± 2% -43.52% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
FindAllNoMatches-8 240B ± 0% 0B -100.00% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
FindAllNoMatches-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
This work was supported by Sourcegraph.
Change-Id: I30aac201370ccfb40a6ff637402020ac20f61f70
Reviewed-on: https://go-review.googlesource.com/87418
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/regexp')
-rw-r--r-- | src/regexp/all_test.go | 13 | ||||
-rw-r--r-- | src/regexp/regexp.go | 64 |
2 files changed, 45 insertions, 32 deletions
diff --git a/src/regexp/all_test.go b/src/regexp/all_test.go index 28fe20c15d..0fabeae59f 100644 --- a/src/regexp/all_test.go +++ b/src/regexp/all_test.go @@ -581,6 +581,19 @@ func BenchmarkFind(b *testing.B) { } } +func BenchmarkFindAllNoMatches(b *testing.B) { + re := MustCompile("a+b+") + s := []byte("acddee") + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + all := re.FindAll(s, -1) + if all != nil { + b.Fatalf("FindAll(%q) = %q; want nil", s, all) + } + } +} + func BenchmarkFindString(b *testing.B) { b.StopTimer() re := MustCompile("a+b+") diff --git a/src/regexp/regexp.go b/src/regexp/regexp.go index b1af23e850..023920c91e 100644 --- a/src/regexp/regexp.go +++ b/src/regexp/regexp.go @@ -984,13 +984,13 @@ func (re *Regexp) FindAll(b []byte, n int) [][]byte { if n < 0 { n = len(b) + 1 } - result := make([][]byte, 0, startSize) + var result [][]byte re.allMatches("", b, n, func(match []int) { + if result == nil { + result = make([][]byte, 0, startSize) + } result = append(result, b[match[0]:match[1]]) }) - if len(result) == 0 { - return nil - } return result } @@ -1002,13 +1002,13 @@ func (re *Regexp) FindAllIndex(b []byte, n int) [][]int { if n < 0 { n = len(b) + 1 } - result := make([][]int, 0, startSize) + var result [][]int re.allMatches("", b, n, func(match []int) { + if result == nil { + result = make([][]int, 0, startSize) + } result = append(result, match[0:2]) }) - if len(result) == 0 { - return nil - } return result } @@ -1020,13 +1020,13 @@ func (re *Regexp) FindAllString(s string, n int) []string { if n < 0 { n = len(s) + 1 } - result := make([]string, 0, startSize) + var result []string re.allMatches(s, nil, n, func(match []int) { + if result == nil { + result = make([]string, 0, startSize) + } result = append(result, s[match[0]:match[1]]) }) - if len(result) == 0 { - return nil - } return result } @@ -1038,13 +1038,13 @@ func (re *Regexp) FindAllStringIndex(s string, n int) [][]int { if n < 0 { n = len(s) + 1 } - result := make([][]int, 0, startSize) + var result [][]int re.allMatches(s, nil, n, func(match []int) { + if result == nil { + result = make([][]int, 0, startSize) + } result = append(result, match[0:2]) }) - if len(result) == 0 { - return nil - } return result } @@ -1056,8 +1056,11 @@ func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte { if n < 0 { n = len(b) + 1 } - result := make([][][]byte, 0, startSize) + var result [][][]byte re.allMatches("", b, n, func(match []int) { + if result == nil { + result = make([][][]byte, 0, startSize) + } slice := make([][]byte, len(match)/2) for j := range slice { if match[2*j] >= 0 { @@ -1066,9 +1069,6 @@ func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte { } result = append(result, slice) }) - if len(result) == 0 { - return nil - } return result } @@ -1080,13 +1080,13 @@ func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int { if n < 0 { n = len(b) + 1 } - result := make([][]int, 0, startSize) + var result [][]int re.allMatches("", b, n, func(match []int) { + if result == nil { + result = make([][]int, 0, startSize) + } result = append(result, match) }) - if len(result) == 0 { - return nil - } return result } @@ -1098,8 +1098,11 @@ func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string { if n < 0 { n = len(s) + 1 } - result := make([][]string, 0, startSize) + var result [][]string re.allMatches(s, nil, n, func(match []int) { + if result == nil { + result = make([][]string, 0, startSize) + } slice := make([]string, len(match)/2) for j := range slice { if match[2*j] >= 0 { @@ -1108,9 +1111,6 @@ func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string { } result = append(result, slice) }) - if len(result) == 0 { - return nil - } return result } @@ -1123,13 +1123,13 @@ func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int { if n < 0 { n = len(s) + 1 } - result := make([][]int, 0, startSize) + var result [][]int re.allMatches(s, nil, n, func(match []int) { + if result == nil { + result = make([][]int, 0, startSize) + } result = append(result, match) }) - if len(result) == 0 { - return nil - } return result } |