Commit 90351506 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

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
parent 2fe9a5a3
......@@ -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 {
op |= EmptyBeginText | EmptyBeginLine
}
if r1 == '\n' {
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 r2 < 0 {
op |= EmptyEndText | EmptyEndLine
}
if r2 == '\n' {
switch {
case IsWordChar(r2):
boundary ^= 1
case r2 == '\n':
op |= EmptyEndLine
case r2 < 0:
op |= EmptyEndText | EmptyEndLine
}
if IsWordChar(r1) != IsWordChar(r2) {
op |= EmptyWordBoundary
} else {
op |= EmptyNoWordBoundary
if boundary != 0 { // IsWordChar(r1) != IsWordChar(r2)
op ^= (EmptyWordBoundary | EmptyNoWordBoundary)
}
return op
}
......
......@@ -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)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment