aboutsummaryrefslogtreecommitdiff
path: root/src/regexp
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2017-12-18 10:53:55 -0800
committerBrad Fitzpatrick <bradfitz@golang.org>2018-02-13 18:44:40 +0000
commitdf5997b99b9a89e1198596366230fa6c4dd50b70 (patch)
treee52ebadceac886d89e1debc251f3eeca21a2816c /src/regexp
parent4b8a7eafef039af1834ef9bfa879257c4a72b7b5 (diff)
downloadgo-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.go13
-rw-r--r--src/regexp/regexp.go64
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
}