diff options
author | Kevin Burke <kev@inburke.com> | 2017-04-23 22:19:35 -0700 |
---|---|---|
committer | Kevin Burke <kev@inburke.com> | 2017-04-28 06:43:14 +0000 |
commit | 89ebdbb5fd548051339705687c25d1d89abc4539 (patch) | |
tree | 213aab74e25aad4478207fbb729264bd4aff2f7d /src/regexp/regexp.go | |
parent | 642a1cc7563953bf2be39eca461325bfa9735cde (diff) | |
download | go-git-89ebdbb5fd548051339705687c25d1d89abc4539.tar.gz |
regexp: speed up QuoteMeta with a lookup table
This is the same technique used in CL 24466. By adding a little bit of
size to the binary, we can remove a function call and gain a lot of
performance.
A raw array ([128]bool) would be faster, but is also be 128 bytes
instead of 16.
Running tip on a Mac:
name old time/op new time/op delta
QuoteMetaAll-4 192ns ±12% 120ns ±11% -37.27% (p=0.000 n=10+10)
QuoteMetaNone-4 186ns ± 6% 64ns ± 6% -65.52% (p=0.000 n=10+10)
name old speed new speed delta
QuoteMetaAll-4 73.2MB/s ±11% 116.6MB/s ±10% +59.21% (p=0.000 n=10+10)
QuoteMetaNone-4 139MB/s ± 6% 405MB/s ± 6% +190.74% (p=0.000 n=10+10)
Change-Id: I68ce9fe2ef1c28e2274157789b35b0dd6ae3efb5
Reviewed-on: https://go-review.googlesource.com/41495
Run-TryBot: Kevin Burke <kev@inburke.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/regexp/regexp.go')
-rw-r--r-- | src/regexp/regexp.go | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/regexp/regexp.go b/src/regexp/regexp.go index 924b011991..b1af23e850 100644 --- a/src/regexp/regexp.go +++ b/src/regexp/regexp.go @@ -609,10 +609,18 @@ func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte { }) } -var specialBytes = []byte(`\.+*?()|[]{}^$`) +// Bitmap used by func special to check whether a character needs to be escaped. +var specialBytes [16]byte +// special reports whether byte b needs to be escaped by QuoteMeta. func special(b byte) bool { - return bytes.IndexByte(specialBytes, b) >= 0 + return b < utf8.RuneSelf && specialBytes[b%16]&(1<<(b/16)) != 0 +} + +func init() { + for _, b := range []byte(`\.+*?()|[]{}^$`) { + specialBytes[b%16] |= 1 << (b / 16) + } } // QuoteMeta returns a string that quotes all regular expression metacharacters |