summaryrefslogtreecommitdiff
path: root/src/regexp/all_test.go
Commit message (Collapse)AuthorAgeFilesLines
* regexp: add (*Regexp).SubexpIndexSylvain Zimmer2020-04-101-14/+28
| | | | | | | | | | | | | SubexpIndex returns the index of the first subexpression with the given name, or -1 if there is no subexpression with that name. Fixes #32420 Change-Id: Ie1f9d22d50fb84e18added80a9d9a9f6dca8ffc4 Reviewed-on: https://go-review.googlesource.com/c/go/+/187919 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
* regexp: optimize for provably too short inputsSylvain Zimmer2019-05-151-0/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For many patterns we can compute the minimum input length at compile time. If the input is shorter, we can return early and get a huge speedup. As pointed out by Damian Gryski, Perl's regex engine contains a number of these kinds of fail-fast optimizations: https://perldoc.perl.org/perlreguts.html#Peep-hole-Optimisation-and-Analysis Benchmarks: (including new ones for compile time) name old time/op new time/op delta Compile/Onepass-8 4.39µs ± 1% 4.40µs ± 0% +0.34% (p=0.029 n=9+8) Compile/Medium-8 9.80µs ± 0% 9.91µs ± 0% +1.17% (p=0.000 n=10+10) Compile/Hard-8 72.7µs ± 0% 73.5µs ± 0% +1.10% (p=0.000 n=9+10) name old time/op new time/op delta Match/Easy0/16-8 52.6ns ± 5% 4.9ns ± 0% -90.68% (p=0.000 n=10+9) Match/Easy0/32-8 64.1ns ±10% 61.4ns ± 1% ~ (p=0.188 n=10+9) Match/Easy0/1K-8 280ns ± 1% 277ns ± 2% -0.97% (p=0.004 n=10+10) Match/Easy0/32K-8 4.61µs ± 1% 4.55µs ± 1% -1.49% (p=0.000 n=9+10) Match/Easy0/1M-8 229µs ± 0% 226µs ± 1% -1.29% (p=0.000 n=8+10) Match/Easy0/32M-8 7.50ms ± 1% 7.47ms ± 1% ~ (p=0.165 n=10+10) Match/Easy0i/16-8 533ns ± 1% 5ns ± 2% -99.07% (p=0.000 n=10+10) Match/Easy0i/32-8 950ns ± 0% 950ns ± 1% ~ (p=0.920 n=10+9) Match/Easy0i/1K-8 27.5µs ± 1% 27.5µs ± 0% ~ (p=0.739 n=10+10) Match/Easy0i/32K-8 1.13ms ± 0% 1.13ms ± 1% ~ (p=0.079 n=9+10) Match/Easy0i/1M-8 36.7ms ± 2% 36.1ms ± 0% -1.64% (p=0.000 n=10+9) Match/Easy0i/32M-8 1.17s ± 0% 1.16s ± 1% -0.80% (p=0.004 n=8+9) Match/Easy1/16-8 55.5ns ± 6% 4.9ns ± 1% -91.19% (p=0.000 n=10+9) Match/Easy1/32-8 58.3ns ± 8% 56.6ns ± 1% ~ (p=0.449 n=10+8) Match/Easy1/1K-8 750ns ± 0% 748ns ± 1% ~ (p=0.072 n=8+10) Match/Easy1/32K-8 31.8µs ± 0% 31.6µs ± 1% -0.50% (p=0.035 n=10+9) Match/Easy1/1M-8 1.10ms ± 1% 1.09ms ± 0% -0.95% (p=0.000 n=10+9) Match/Easy1/32M-8 35.5ms ± 0% 35.2ms ± 1% -1.05% (p=0.000 n=9+10) Match/Medium/16-8 442ns ± 2% 5ns ± 1% -98.89% (p=0.000 n=10+10) Match/Medium/32-8 875ns ± 0% 878ns ± 1% ~ (p=0.071 n=9+10) Match/Medium/1K-8 26.1µs ± 0% 25.9µs ± 0% -0.64% (p=0.000 n=10+10) Match/Medium/32K-8 1.09ms ± 1% 1.08ms ± 0% -0.84% (p=0.000 n=10+9) Match/Medium/1M-8 34.9ms ± 0% 34.6ms ± 1% -0.98% (p=0.000 n=9+10) Match/Medium/32M-8 1.12s ± 1% 1.11s ± 1% -0.98% (p=0.000 n=10+9) Match/Hard/16-8 721ns ± 1% 5ns ± 0% -99.32% (p=0.000 n=10+9) Match/Hard/32-8 1.32µs ± 1% 1.31µs ± 0% -0.71% (p=0.000 n=9+9) Match/Hard/1K-8 39.8µs ± 1% 39.7µs ± 1% ~ (p=0.165 n=10+10) Match/Hard/32K-8 1.57ms ± 0% 1.56ms ± 0% -0.70% (p=0.000 n=10+9) Match/Hard/1M-8 50.4ms ± 1% 50.1ms ± 1% -0.57% (p=0.007 n=10+10) Match/Hard/32M-8 1.62s ± 1% 1.60s ± 0% -0.98% (p=0.000 n=10+10) Match/Hard1/16-8 3.88µs ± 1% 3.86µs ± 0% ~ (p=0.118 n=10+10) Match/Hard1/32-8 7.44µs ± 1% 7.46µs ± 1% ~ (p=0.109 n=10+10) Match/Hard1/1K-8 232µs ± 1% 229µs ± 1% -1.31% (p=0.000 n=10+9) Match/Hard1/32K-8 7.41ms ± 2% 7.41ms ± 0% ~ (p=0.237 n=10+8) Match/Hard1/1M-8 238ms ± 1% 238ms ± 0% ~ (p=0.481 n=10+10) Match/Hard1/32M-8 7.69s ± 1% 7.61s ± 0% -1.00% (p=0.000 n=10+10) Fixes #31329 Change-Id: I04640e8c59178ec8b3106e13ace9b109b6bdbc25 Reviewed-on: https://go-review.googlesource.com/c/go/+/171023 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Rob Pike <r@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
* regexp: add DeepEqual testRuss Cox2018-10-121-0/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This locks in behavior we accidentally broke and then restored during the Go 1.11 cycle. See #26219. It also locks in new behavior that DeepEqual always works, instead of only usually working. This CL is the final piece of a series of CLs to make DeepEqual always work, by eliminating the machine cache and making other related optimizations. Overall, this whole sequence of CLs achieves: name old time/op new time/op delta Find-12 264ns ± 3% 260ns ± 0% -1.59% (p=0.000 n=10+9) FindAllNoMatches-12 140ns ± 2% 133ns ± 0% -5.34% (p=0.000 n=10+7) FindString-12 256ns ± 0% 249ns ± 0% -2.73% (p=0.000 n=8+8) FindSubmatch-12 339ns ± 1% 333ns ± 1% -1.73% (p=0.000 n=9+10) FindStringSubmatch-12 322ns ± 0% 322ns ± 1% ~ (p=0.450 n=8+10) Literal-12 100ns ± 2% 92ns ± 0% -8.13% (p=0.000 n=10+10) NotLiteral-12 1.50µs ± 0% 1.47µs ± 0% -1.65% (p=0.000 n=8+8) MatchClass-12 2.18µs ± 0% 2.15µs ± 0% -1.05% (p=0.000 n=10+9) MatchClass_InRange-12 2.12µs ± 0% 2.11µs ± 0% -0.65% (p=0.000 n=10+9) ReplaceAll-12 1.41µs ± 0% 1.41µs ± 0% ~ (p=0.254 n=7+10) AnchoredLiteralShortNonMatch-12 89.8ns ± 0% 81.5ns ± 0% -9.22% (p=0.000 n=8+9) AnchoredLiteralLongNonMatch-12 105ns ± 3% 97ns ± 0% -7.21% (p=0.000 n=10+10) AnchoredShortMatch-12 141ns ± 0% 128ns ± 0% -9.22% (p=0.000 n=9+9) AnchoredLongMatch-12 276ns ± 4% 253ns ± 2% -8.23% (p=0.000 n=10+10) OnePassShortA-12 620ns ± 0% 587ns ± 0% -5.26% (p=0.000 n=10+6) NotOnePassShortA-12 575ns ± 3% 547ns ± 1% -4.77% (p=0.000 n=10+10) OnePassShortB-12 493ns ± 0% 455ns ± 0% -7.62% (p=0.000 n=8+9) NotOnePassShortB-12 423ns ± 0% 406ns ± 1% -3.95% (p=0.000 n=8+10) OnePassLongPrefix-12 112ns ± 0% 109ns ± 1% -2.77% (p=0.000 n=9+10) OnePassLongNotPrefix-12 405ns ± 0% 349ns ± 0% -13.74% (p=0.000 n=8+9) MatchParallelShared-12 501ns ± 1% 38ns ± 2% -92.42% (p=0.000 n=10+10) MatchParallelCopied-12 39.1ns ± 0% 38.6ns ± 1% -1.38% (p=0.002 n=6+10) QuoteMetaAll-12 94.6ns ± 0% 94.8ns ± 0% +0.26% (p=0.001 n=10+9) QuoteMetaNone-12 52.7ns ± 0% 52.7ns ± 0% ~ (all equal) Match/Easy0/32-12 79.1ns ± 0% 72.0ns ± 0% -8.95% (p=0.000 n=9+9) Match/Easy0/1K-12 307ns ± 1% 297ns ± 0% -3.32% (p=0.000 n=10+7) Match/Easy0/32K-12 4.65µs ± 2% 4.67µs ± 1% ~ (p=0.633 n=10+8) Match/Easy0/1M-12 234µs ± 0% 234µs ± 0% ~ (p=0.684 n=10+10) Match/Easy0/32M-12 7.98ms ± 1% 7.96ms ± 0% -0.31% (p=0.014 n=9+9) Match/Easy0i/32-12 1.13µs ± 1% 1.10µs ± 0% -3.18% (p=0.000 n=9+10) Match/Easy0i/1K-12 32.5µs ± 0% 31.7µs ± 0% -2.61% (p=0.000 n=9+9) Match/Easy0i/32K-12 1.59ms ± 0% 1.26ms ± 0% -20.71% (p=0.000 n=9+7) Match/Easy0i/1M-12 51.0ms ± 0% 40.4ms ± 0% -20.68% (p=0.000 n=10+7) Match/Easy0i/32M-12 1.63s ± 0% 1.30s ± 0% -20.62% (p=0.001 n=7+7) Match/Easy1/32-12 75.1ns ± 1% 67.4ns ± 0% -10.24% (p=0.000 n=8+10) Match/Easy1/1K-12 861ns ± 0% 879ns ± 0% +2.18% (p=0.000 n=8+8) Match/Easy1/32K-12 39.2µs ± 1% 34.1µs ± 0% -13.01% (p=0.000 n=10+8) Match/Easy1/1M-12 1.38ms ± 0% 1.17ms ± 0% -15.06% (p=0.000 n=10+8) Match/Easy1/32M-12 44.2ms ± 1% 37.5ms ± 0% -15.15% (p=0.000 n=10+9) Match/Medium/32-12 1.04µs ± 1% 1.03µs ± 0% -0.64% (p=0.002 n=9+8) Match/Medium/1K-12 31.3µs ± 0% 31.2µs ± 0% -0.36% (p=0.000 n=9+9) Match/Medium/32K-12 1.44ms ± 0% 1.20ms ± 0% -17.02% (p=0.000 n=8+7) Match/Medium/1M-12 46.1ms ± 0% 38.2ms ± 0% -17.14% (p=0.001 n=6+8) Match/Medium/32M-12 1.48s ± 0% 1.23s ± 0% -17.10% (p=0.000 n=9+7) Match/Hard/32-12 1.54µs ± 1% 1.47µs ± 0% -4.64% (p=0.000 n=9+10) Match/Hard/1K-12 46.4µs ± 1% 44.4µs ± 0% -4.35% (p=0.000 n=9+8) Match/Hard/32K-12 2.19ms ± 0% 1.78ms ± 7% -18.74% (p=0.000 n=8+10) Match/Hard/1M-12 70.1ms ± 0% 57.7ms ± 7% -17.62% (p=0.000 n=8+10) Match/Hard/32M-12 2.24s ± 0% 1.84s ± 8% -17.92% (p=0.000 n=8+10) Match/Hard1/32-12 8.17µs ± 1% 7.95µs ± 0% -2.72% (p=0.000 n=8+10) Match/Hard1/1K-12 254µs ± 2% 245µs ± 0% -3.62% (p=0.000 n=9+10) Match/Hard1/32K-12 9.58ms ± 1% 8.54ms ± 7% -10.87% (p=0.000 n=10+10) Match/Hard1/1M-12 306ms ± 1% 271ms ± 8% -11.42% (p=0.000 n=9+10) Match/Hard1/32M-12 9.79s ± 1% 8.58s ± 9% -12.37% (p=0.000 n=9+10) Match_onepass_regex/32-12 808ns ± 0% 716ns ± 1% -11.39% (p=0.000 n=8+9) Match_onepass_regex/1K-12 27.8µs ± 0% 19.9µs ± 2% -28.51% (p=0.000 n=8+9) Match_onepass_regex/32K-12 925µs ± 0% 631µs ± 2% -31.71% (p=0.000 n=9+9) Match_onepass_regex/1M-12 29.5ms ± 0% 20.2ms ± 2% -31.53% (p=0.000 n=10+9) Match_onepass_regex/32M-12 945ms ± 0% 648ms ± 2% -31.39% (p=0.000 n=9+9) CompileOnepass-12 4.67µs ± 0% 4.60µs ± 0% -1.48% (p=0.000 n=10+10) [Geo mean] 24.5µs 21.4µs -12.94% https://perf.golang.org/search?q=upload:20181004.5 Change-Id: Icb17b306830dc5489efbb55900937b94ce0eb047 Reviewed-on: https://go-review.googlesource.com/c/139783 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
* regexp: split one-pass execution out of machine structRuss Cox2018-10-121-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This allows the one-pass executions to have their own pool of (much smaller) allocated structures. A step toward eliminating the per-Regexp machine cache. Not much effect on benchmarks, since there are no optimizations here, and pools are a tiny bit slower than a locked data structure for single-threaded code. name old time/op new time/op delta Find-12 254ns ± 0% 252ns ± 0% -0.94% (p=0.000 n=9+10) FindAllNoMatches-12 135ns ± 0% 134ns ± 1% -0.49% (p=0.002 n=9+9) FindString-12 247ns ± 0% 246ns ± 0% -0.24% (p=0.003 n=8+10) FindSubmatch-12 334ns ± 0% 333ns ± 2% ~ (p=0.283 n=10+10) FindStringSubmatch-12 321ns ± 0% 320ns ± 0% -0.51% (p=0.000 n=9+10) Literal-12 92.2ns ± 0% 91.1ns ± 0% -1.25% (p=0.000 n=9+10) NotLiteral-12 1.47µs ± 0% 1.45µs ± 0% -0.99% (p=0.000 n=9+10) MatchClass-12 2.17µs ± 0% 2.19µs ± 0% +0.84% (p=0.000 n=7+9) MatchClass_InRange-12 2.13µs ± 0% 2.09µs ± 0% -1.70% (p=0.000 n=10+10) ReplaceAll-12 1.39µs ± 0% 1.39µs ± 0% +0.51% (p=0.000 n=10+10) AnchoredLiteralShortNonMatch-12 83.2ns ± 0% 82.4ns ± 0% -0.96% (p=0.000 n=8+8) AnchoredLiteralLongNonMatch-12 105ns ± 0% 106ns ± 1% ~ (p=0.087 n=10+10) AnchoredShortMatch-12 131ns ± 0% 130ns ± 0% -0.76% (p=0.000 n=10+9) AnchoredLongMatch-12 267ns ± 0% 272ns ± 0% +2.01% (p=0.000 n=10+8) OnePassShortA-12 611ns ± 0% 615ns ± 0% +0.61% (p=0.000 n=9+10) NotOnePassShortA-12 552ns ± 0% 549ns ± 0% -0.46% (p=0.000 n=8+9) OnePassShortB-12 491ns ± 0% 494ns ± 0% +0.61% (p=0.000 n=8+8) NotOnePassShortB-12 412ns ± 0% 412ns ± 1% ~ (p=0.151 n=9+10) OnePassLongPrefix-12 112ns ± 0% 108ns ± 0% -3.57% (p=0.000 n=10+10) OnePassLongNotPrefix-12 410ns ± 0% 402ns ± 0% -1.95% (p=0.000 n=9+8) MatchParallelShared-12 38.8ns ± 1% 38.6ns ± 2% ~ (p=0.536 n=10+9) MatchParallelCopied-12 39.2ns ± 3% 39.4ns ± 7% ~ (p=0.986 n=10+10) QuoteMetaAll-12 94.6ns ± 0% 94.9ns ± 0% +0.29% (p=0.001 n=8+9) QuoteMetaNone-12 52.7ns ± 0% 52.7ns ± 0% ~ (all equal) Match/Easy0/32-12 72.9ns ± 0% 72.1ns ± 0% -1.07% (p=0.000 n=9+9) Match/Easy0/1K-12 298ns ± 0% 298ns ± 0% ~ (p=0.140 n=6+8) Match/Easy0/32K-12 4.60µs ± 2% 4.64µs ± 1% ~ (p=0.171 n=10+10) Match/Easy0/1M-12 235µs ± 0% 234µs ± 0% -0.14% (p=0.004 n=10+10) Match/Easy0/32M-12 7.96ms ± 0% 7.95ms ± 0% -0.12% (p=0.043 n=10+9) Match/Easy0i/32-12 1.09µs ± 0% 1.10µs ± 0% +0.15% (p=0.000 n=8+9) Match/Easy0i/1K-12 31.7µs ± 0% 31.8µs ± 1% ~ (p=0.905 n=9+10) Match/Easy0i/32K-12 1.61ms ± 0% 1.62ms ± 1% +1.12% (p=0.000 n=9+10) Match/Easy0i/1M-12 51.4ms ± 0% 51.8ms ± 0% +0.85% (p=0.000 n=8+8) Match/Easy0i/32M-12 1.65s ± 1% 1.65s ± 0% ~ (p=0.113 n=9+9) Match/Easy1/32-12 67.9ns ± 0% 67.7ns ± 1% ~ (p=0.232 n=8+10) Match/Easy1/1K-12 884ns ± 0% 873ns ± 0% -1.29% (p=0.000 n=9+10) Match/Easy1/32K-12 39.2µs ± 0% 39.4µs ± 0% +0.50% (p=0.000 n=9+10) Match/Easy1/1M-12 1.39ms ± 0% 1.39ms ± 0% +0.29% (p=0.000 n=9+10) Match/Easy1/32M-12 44.2ms ± 1% 44.3ms ± 0% +0.21% (p=0.029 n=10+10) Match/Medium/32-12 1.05µs ± 0% 1.04µs ± 0% -0.27% (p=0.001 n=8+9) Match/Medium/1K-12 31.3µs ± 0% 31.4µs ± 0% +0.39% (p=0.000 n=9+8) Match/Medium/32K-12 1.45ms ± 0% 1.45ms ± 0% +0.33% (p=0.000 n=8+9) Match/Medium/1M-12 46.2ms ± 0% 46.4ms ± 0% +0.35% (p=0.000 n=9+8) Match/Medium/32M-12 1.48s ± 0% 1.49s ± 1% +0.70% (p=0.000 n=8+10) Match/Hard/32-12 1.49µs ± 0% 1.48µs ± 0% -0.43% (p=0.000 n=10+9) Match/Hard/1K-12 45.1µs ± 1% 45.0µs ± 1% ~ (p=0.393 n=10+10) Match/Hard/32K-12 2.18ms ± 1% 2.24ms ± 0% +2.71% (p=0.000 n=9+8) Match/Hard/1M-12 69.7ms ± 1% 71.6ms ± 0% +2.76% (p=0.000 n=9+7) Match/Hard/32M-12 2.23s ± 1% 2.29s ± 0% +2.65% (p=0.000 n=9+9) Match/Hard1/32-12 7.89µs ± 0% 7.89µs ± 0% ~ (p=0.286 n=9+9) Match/Hard1/1K-12 244µs ± 0% 244µs ± 0% ~ (p=0.905 n=9+10) Match/Hard1/32K-12 10.3ms ± 0% 10.3ms ± 0% ~ (p=0.796 n=10+10) Match/Hard1/1M-12 331ms ± 0% 331ms ± 0% ~ (p=0.167 n=8+9) Match/Hard1/32M-12 10.6s ± 0% 10.6s ± 0% ~ (p=0.315 n=8+10) Match_onepass_regex/32-12 812ns ± 0% 830ns ± 0% +2.19% (p=0.000 n=10+9) Match_onepass_regex/1K-12 28.5µs ± 0% 28.7µs ± 1% +0.97% (p=0.000 n=10+9) Match_onepass_regex/32K-12 936µs ± 0% 949µs ± 0% +1.43% (p=0.000 n=10+8) Match_onepass_regex/1M-12 30.2ms ± 0% 30.4ms ± 0% +0.62% (p=0.000 n=10+8) Match_onepass_regex/32M-12 970ms ± 0% 973ms ± 0% +0.35% (p=0.000 n=10+9) CompileOnepass-12 4.63µs ± 1% 4.64µs ± 0% ~ (p=0.060 n=10+10) [Geo mean] 23.3µs 23.3µs +0.12% https://perf.golang.org/search?q=upload:20181004.2 Change-Id: Iff9e9f9d4a4698162126a2f300e8ed1b1a39361e Reviewed-on: https://go-review.googlesource.com/c/139780 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
* regexp: don't allocate when All methods find no matchesJosh Bleecher Snyder2018-02-131-0/+13
| | | | | | | | | | | | | | | | | | | | 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>
* regexp: speed up QuoteMeta with a lookup tableKevin Burke2017-04-281-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* regexp: avoid alloc in QuoteMeta when not quotingIngo Oeser2016-10-191-0/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Many users quote literals in regular expressions just in case. No need to allocate then. Note: Also added benchmarks for quoting and not quoting. name old time/op new time/op delta QuoteMetaAll-4 629ns ± 6% 654ns ± 5% +4.01% (p=0.001 n=20+19) QuoteMetaNone-4 1.02µs ± 6% 0.20µs ± 0% -80.73% (p=0.000 n=18+20) name old speed new speed delta QuoteMetaAll-4 22.3MB/s ± 6% 21.4MB/s ± 5% -3.94% (p=0.001 n=20+19) QuoteMetaNone-4 25.3MB/s ± 3% 131.5MB/s ± 0% +419.28% (p=0.000 n=17+19) name old alloc/op new alloc/op delta QuoteMetaAll-4 64.0B ± 0% 64.0B ± 0% ~ (all samples are equal) QuoteMetaNone-4 96.0B ± 0% 0.0B ±NaN% -100.00% (p=0.000 n=20+20) name old allocs/op new allocs/op delta QuoteMetaAll-4 2.00 ± 0% 2.00 ± 0% ~ (all samples are equal) QuoteMetaNone-4 2.00 ± 0% 0.00 ±NaN% -100.00% (p=0.000 n=20+20) Change-Id: I38d50f463cde463115d22534f8eb849e54d899af Reviewed-on: https://go-review.googlesource.com/31395 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
* regexp: reduce mallocs in Regexp.Find* and Regexp.ReplaceAll*.Aliaksandr Valialkin2016-09-061-0/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This improves Regexp.Find* and Regexp.ReplaceAll* speed: name old time/op new time/op delta Find-4 345ns ± 1% 314ns ± 1% -8.94% (p=0.000 n=9+8) FindString-4 341ns ± 1% 308ns ± 0% -9.85% (p=0.000 n=10+9) FindSubmatch-4 440ns ± 1% 404ns ± 0% -8.27% (p=0.000 n=10+8) FindStringSubmatch-4 426ns ± 0% 387ns ± 0% -9.07% (p=0.000 n=10+9) ReplaceAll-4 1.75µs ± 1% 1.67µs ± 0% -4.45% (p=0.000 n=9+10) name old alloc/op new alloc/op delta Find-4 16.0B ± 0% 0.0B ±NaN% -100.00% (p=0.000 n=10+10) FindString-4 16.0B ± 0% 0.0B ±NaN% -100.00% (p=0.000 n=10+10) FindSubmatch-4 80.0B ± 0% 48.0B ± 0% -40.00% (p=0.000 n=10+10) FindStringSubmatch-4 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=10+10) ReplaceAll-4 152B ± 0% 104B ± 0% -31.58% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Find-4 1.00 ± 0% 0.00 ±NaN% -100.00% (p=0.000 n=10+10) FindString-4 1.00 ± 0% 0.00 ±NaN% -100.00% (p=0.000 n=10+10) FindSubmatch-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) FindStringSubmatch-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) ReplaceAll-4 8.00 ± 0% 5.00 ± 0% -37.50% (p=0.000 n=10+10) Fixes #15643 Change-Id: I594fe51172373e2adb98d1d25c76ca2cde54ff48 Reviewed-on: https://go-review.googlesource.com/23030 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
* regexp: add some tests that were fixed in #12980Tamir Duberstein2016-08-161-6/+32
| | | | | | | | | | Also includes a minor golint cleanup in the tests. Change-Id: I8c0fc81479e635e7cca18d5c48c28b654afa59d8 Reviewed-on: https://go-review.googlesource.com/25380 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
* regexp: fix LiteralPrefix for certain onepass progsCaleb Spare2015-11-251-1/+14
| | | | | | | | | | | | | | | | The prefix computation for onepass was incorrectly returning complete=true when it encountered a beginning-of-text empty width match (^) in the middle of an expression. Fix by returning complete only when the prefix is followed by $ and then an accepting state. Fixes #11175. Change-Id: Ie9c4cf5f76c1d2c904a6fb2f016cedb265c19fde Reviewed-on: https://go-review.googlesource.com/16200 TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
* regexp: add Copy method to RegexpCaleb Spare2015-11-251-0/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This helps users who wish to use separate Regexps in each goroutine to avoid lock contention. Previously they had to parse the expression multiple times to achieve this. I used variants of the included benchmark to evaluate this change. I used the arguments -benchtime 20s -cpu 1,2,4,8,16 on a machine with 16 hardware cores. Comparing a single shared Regexp vs. copied Regexps, we can see that lock contention causes huge slowdowns at higher levels of parallelism. The copied version shows the expected linear speedup. name old time/op new time/op delta MatchParallel 366ns ± 0% 370ns ± 0% +1.09% (p=0.000 n=10+8) MatchParallel-2 324ns ±28% 184ns ± 1% -43.37% (p=0.000 n=10+10) MatchParallel-4 352ns ± 5% 93ns ± 1% -73.70% (p=0.000 n=9+10) MatchParallel-8 480ns ± 3% 46ns ± 0% -90.33% (p=0.000 n=9+8) MatchParallel-16 510ns ± 8% 24ns ± 6% -95.36% (p=0.000 n=10+8) I also compared a modified version of Regexp that has no mutex and a single machine (the "RegexpForSingleGoroutine" rsc mentioned in https://github.com/golang/go/issues/8232#issuecomment-66096128). In this next test, I compared using N copied Regexps vs. N separate RegexpForSingleGoroutines. This shows that, even for this relatively simple regex, avoiding the lock entirely would only buy about 10-12% further improvement. name old time/op new time/op delta MatchParallel 370ns ± 0% 322ns ± 0% -12.97% (p=0.000 n=8+8) MatchParallel-2 184ns ± 1% 162ns ± 1% -11.60% (p=0.000 n=10+10) MatchParallel-4 92.7ns ± 1% 81.1ns ± 2% -12.43% (p=0.000 n=10+10) MatchParallel-8 46.4ns ± 0% 41.8ns ±10% -9.78% (p=0.000 n=8+10) MatchParallel-16 23.7ns ± 6% 20.6ns ± 1% -13.14% (p=0.000 n=8+8) Updates #8232. Change-Id: I15201a080c363d1b44104eafed46d8df5e311902 Reviewed-on: https://go-review.googlesource.com/16110 Reviewed-by: Russ Cox <rsc@golang.org>
* regexp: fix slice bounds out of range panicsDidier Spezia2015-10-231-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Regular expressions involving a (x){0} term are simplified by removing this term from the expression, just before the expression is compiled. The number of subexpressions is evaluated before the simplification. The number of capture instructions in the compiled expressions is not necessarily in line with the number of subexpressions. When the ReplaceAll(String) methods are used, a number of capture slots (nmatch) is evaluated as 2*(s+1) (s being the number of subexpressions). In some case, it can be higher than the number of capture instructions evaluated at compile time, resulting in a panic when the internal slices of regexp.machine are resized to this value. Fixed by capping the number of capture slots to the number of capture instructions. I must say I do not really see the benefits of setting nmatch lower than re.prog.NumCap using this 2*(s+1) formula, so perhaps this can be further simplified. Fixes #11178 Fixes #11176 Change-Id: I21415e8ef2dd5f2721218e9a679f7f6bfb76ae9b Reviewed-on: https://go-review.googlesource.com/14013 Reviewed-by: Russ Cox <rsc@golang.org>
* regexp: set b.cap[0] and b.cap[1] only when captures requestedMichael Matloob2015-04-171-0/+11
| | | | | | | | | Fixes #10319 Change-Id: I96015b0e1dff30a72de11fea3837638b5c672891 Reviewed-on: https://go-review.googlesource.com/8501 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
* regexp: fix TestOnePassCutoffRuss Cox2014-10-201-4/+12
| | | | | | | | | | | | | The stack blowout can no longer happen, but we can still test that too-complex regexps are rejected. Replacement for CL 162770043. LGTM=iant, r R=r, iant CC=bradfitz, golang-codereviews https://golang.org/cl/162860043
* build: move package sources from src/pkg to srcRuss Cox2014-09-081-0/+648
Preparation was in CL 134570043. This CL contains only the effect of 'hg mv src/pkg/* src'. For more about the move, see golang.org/s/go14nopkg.