1
0
mirror of https://github.com/golang/go synced 2024-11-25 09:07:58 -07:00

regexp/syntax: optimize EmptyOpContext

Minor. Saw this in a profile at few percent of CPU and was
curious what it was. Improves overall regexp benchmarks
anywhere from 0 to 3%, but they're a pain to run. You need to
run them in isolation for long runs to get stable numbers.

benchmark                  old ns/op    new ns/op    delta
BenchmarkEmptyOpContext          537          473  -11.92%

R=golang-dev, crawshaw
CC=golang-dev
https://golang.org/cl/13407043
This commit is contained in:
Brad Fitzpatrick 2013-08-29 14:31:10 -07:00
parent 2fe9a5a3e8
commit 90351506d4
2 changed files with 27 additions and 13 deletions

View File

@ -56,23 +56,26 @@ const (
// Passing r2 == -1 indicates that the position is
// at the end of the text.
func EmptyOpContext(r1, r2 rune) EmptyOp {
var op EmptyOp
if r1 < 0 {
var op EmptyOp = EmptyNoWordBoundary
var boundary byte
switch {
case IsWordChar(r1):
boundary = 1
case r1 == '\n':
op |= EmptyBeginLine
case r1 < 0:
op |= EmptyBeginText | EmptyBeginLine
}
if r1 == '\n' {
op |= EmptyBeginLine
}
if r2 < 0 {
switch {
case IsWordChar(r2):
boundary ^= 1
case r2 == '\n':
op |= EmptyEndLine
case r2 < 0:
op |= EmptyEndText | EmptyEndLine
}
if r2 == '\n' {
op |= EmptyEndLine
}
if IsWordChar(r1) != IsWordChar(r2) {
op |= EmptyWordBoundary
} else {
op |= EmptyNoWordBoundary
if boundary != 0 { // IsWordChar(r1) != IsWordChar(r2)
op ^= (EmptyWordBoundary | EmptyNoWordBoundary)
}
return op
}

View File

@ -103,3 +103,14 @@ func TestCompile(t *testing.T) {
}
}
}
func BenchmarkEmptyOpContext(b *testing.B) {
for i := 0; i < b.N; i++ {
var r1 rune = -1
for _, r2 := range "foo, bar, baz\nsome input text.\n" {
EmptyOpContext(r1, r2)
r1 = r2
}
EmptyOpContext(r1, -1)
}
}