Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize long alternate lists #463

Merged
merged 15 commits into from
Apr 1, 2023

Conversation

Logiraptor
Copy link
Contributor

@Logiraptor Logiraptor commented Mar 29, 2023

We've seen that very long regex matchers of the form abc|def|... consume a large amount of CPU both in NewFastRegexMatcher and while matching label values. This PR uses a slice or map to optimize both operations as a special case when the regex is one long alternate of literal values. In that special case, the regex parsing is skipped entirely. As an example, this can occur when using Grafana dashboard template variables with the All option selected.

Unfortunately, this introduces a constant performance cost in NewFastRegexMatcher for other regex queries, but It's not clear that this is actually significant in practice. For example, cpu for a simple case:

NewFastRegexMatcher/^foo-10                                2.396µ ± 2%   2.634µ ± 2%   +9.94% (p=0.002 n=6)

This is a 10% increase, but in concrete terms less than 0.3µs on my laptop.

Here are the results for the specific edge case this PR addresses:

goos: darwin
goarch: arm64
pkg: github.com/prometheus/prometheus/model/labels
                                                        │    before     │                after                │
                                                        │    sec/op     │    sec/op     vs base               │
NewFastRegexMatcher/foo-10                                1978.00n ± 2%   82.61n ±  6%  -95.82% (p=0.002 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10   139.687µ ± 2%   5.787µ ±  1%  -95.86% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10    5726.0µ ± 1%   132.0µ ±  4%  -97.70% (p=0.002 n=6)
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10        740.5n ± 2%   204.2n ±  6%  -72.42% (p=0.002 n=6)
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10       3033.5n ± 1%   217.5n ±  6%  -92.83% (p=0.002 n=6)
geomean                                                     925.9n        749.7n        -19.03%

                                                        │      before      │                  after                   │
                                                        │       B/op       │     B/op      vs base                    │
NewFastRegexMatcher/foo-10                                   3240.0 ± 0%       176.0 ± 0%   -94.57% (p=0.002 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10   248.823Ki ± 0%     4.734Ki ± 0%   -98.10% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10   4417.90Ki ± 0%     80.27Ki ± 0%   -98.18%
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10          0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10          1.000 ± 0%       0.000 ± 0%  -100.00% (p=0.002 n=6) (p=0.002 n=6)
geomean                                                                  ²                 ?                      ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

                                                        │      before      │                after                 │
                                                        │    allocs/op     │  allocs/op   vs base                 │
NewFastRegexMatcher/foo-10                                   53.000 ± 0%      3.000 ± 0%  -94.34% (p=0.002 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10    1228.000 ± 0%      7.000 ± 0%  -99.43% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10   30727.000 ± 0%      6.000 ± 0%  -99.98% (p=0.002 n=6)
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10          0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10          0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
geomean                                                                  ²                -21.74%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

Full Benchmark Results
goos: darwin
goarch: arm64
pkg: github.com/prometheus/prometheus/model/labels
                                                        │    before     │                after                │
                                                        │    sec/op     │    sec/op     vs base               │
NewFastRegexMatcher/foo-10                                1978.00n ± 2%   82.61n ±  6%  -95.82% (p=0.002 n=6)
NewFastRegexMatcher/^foo-10                                 2.396µ ± 2%   2.439µ ± 15%        ~ (p=0.699 n=6)
NewFastRegexMatcher/(foo|bar)-10                            3.753µ ± 1%   4.133µ ±  7%  +10.14% (p=0.002 n=6)
NewFastRegexMatcher/foo.*-10                                2.966µ ± 2%   2.976µ ±  9%        ~ (p=0.485 n=6)
NewFastRegexMatcher/.*foo-10                                2.768µ ± 2%   2.948µ ±  6%   +6.50% (p=0.002 n=6)
NewFastRegexMatcher/^.*foo$-10                              3.168µ ± 2%   3.345µ ±  9%   +5.59% (p=0.004 n=6)
NewFastRegexMatcher/^.+foo$-10                              3.278µ ± 2%   3.390µ ±  6%   +3.40% (p=0.004 n=6)
NewFastRegexMatcher/.*-10                                   1.914µ ± 2%   1.965µ ±  4%   +2.67% (p=0.015 n=6)
NewFastRegexMatcher/.+-10                                   1.844µ ± 4%   1.846µ ±  1%        ~ (p=0.818 n=6)
NewFastRegexMatcher/foo.+-10                                3.043µ ± 1%   3.071µ ±  1%   +0.90% (p=0.024 n=6)
NewFastRegexMatcher/.+foo-10                                2.843µ ± 3%   2.880µ ±  1%        ~ (p=0.310 n=6)
NewFastRegexMatcher/foo_.+-10                               3.212µ ± 2%   3.274µ ±  2%   +1.93% (p=0.009 n=6)
NewFastRegexMatcher/foo_.*-10                               3.201µ ± 2%   3.232µ ±  1%        ~ (p=0.065 n=6)
NewFastRegexMatcher/.*foo.*-10                              3.285µ ± 2%   3.316µ ±  1%   +0.94% (p=0.041 n=6)
NewFastRegexMatcher/.+foo.+-10                              3.319µ ± 2%   3.361µ ±  2%        ~ (p=0.221 n=6)
NewFastRegexMatcher/(?s:.*)-10                              1.991µ ± 2%   2.018µ ±  4%        ~ (p=0.058 n=6)
NewFastRegexMatcher/(?s:.+)-10                              1.950µ ± 1%   1.952µ ±  1%        ~ (p=0.818 n=6)
NewFastRegexMatcher/(?s:^.*foo$)-10                         3.370µ ± 2%   3.373µ ±  1%        ~ (p=0.818 n=6)
NewFastRegexMatcher/(?i:foo)-10                             2.510µ ± 2%   2.539µ ±  1%        ~ (p=0.093 n=6)
NewFastRegexMatcher/(?i:(foo|bar))-10                       4.660µ ± 1%   4.703µ ±  1%        ~ (p=0.071 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|bar))-10                 5.967µ ± 2%   6.067µ ±  5%   +1.68% (p=0.013 n=6)
NewFastRegexMatcher/^(?i:foo|oo)|(bar)$-10                  6.580µ ± 2%   6.605µ ±  5%        ~ (p=0.485 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10     27.83µ ± 2%   27.85µ ±  1%        ~ (p=1.000 n=6)
NewFastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10          8.447µ ± 2%   8.420µ ±  1%        ~ (p=0.937 n=6)
NewFastRegexMatcher/^$-10                                   1.912µ ± 3%   1.941µ ±  1%        ~ (p=0.394 n=6)
NewFastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10      9.039µ ± 2%   9.047µ ±  1%        ~ (p=0.699 n=6)
NewFastRegexMatcher/10\.0\.(1|2)\.+-10                      4.345µ ± 1%   4.377µ ±  1%        ~ (p=0.093 n=6)
NewFastRegexMatcher/10\.0\.(1|2).+-10                       4.692µ ± 2%   4.726µ ±  1%        ~ (p=0.258 n=6)
NewFastRegexMatcher/((fo(bar))|.+foo)-10                    5.782µ ± 3%   5.836µ ±  1%        ~ (p=0.394 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10   139.687µ ± 2%   5.787µ ±  1%  -95.86% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10    5726.0µ ± 1%   132.0µ ±  4%  -97.70% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10     164.1µ ± 2%   162.6µ ±  5%        ~ (p=0.485 n=6)
FastRegexMatcher/foo-10                                     53.39n ± 5%   58.34n ±  2%   +9.28% (p=0.002 n=6)
FastRegexMatcher/^foo-10                                    52.95n ± 4%   52.82n ±  0%        ~ (p=0.394 n=6)
FastRegexMatcher/(foo|bar)-10                               59.55n ± 1%   60.05n ±  0%   +0.85% (p=0.002 n=6)
FastRegexMatcher/foo.*-10                                   88.07n ± 1%   87.54n ±  0%   -0.61% (p=0.009 n=6)
FastRegexMatcher/.*foo-10                                   101.7n ± 1%   101.0n ±  0%   -0.69% (p=0.004 n=6)
FastRegexMatcher/^.*foo$-10                                 101.4n ± 1%   101.0n ±  0%   -0.39% (p=0.030 n=6)
FastRegexMatcher/^.+foo$-10                                 101.9n ± 1%   101.3n ±  1%        ~ (p=0.288 n=6)
FastRegexMatcher/.*-10                                      76.70n ± 1%   75.32n ±  1%   -1.79% (p=0.002 n=6)
FastRegexMatcher/.+-10                                      80.77n ± 0%   78.62n ±  0%   -2.66% (p=0.002 n=6)
FastRegexMatcher/foo.+-10                                   88.32n ± 1%   87.91n ±  1%        ~ (p=0.084 n=6)
FastRegexMatcher/.+foo-10                                   102.0n ± 1%   101.2n ±  0%   -0.69% (p=0.002 n=6)
FastRegexMatcher/foo_.+-10                                  70.77n ± 0%   70.73n ±  0%        ~ (p=0.900 n=6)
FastRegexMatcher/foo_.*-10                                  70.76n ± 2%   70.67n ±  0%        ~ (p=0.818 n=6)
FastRegexMatcher/.*foo.*-10                                 189.1n ± 2%   189.5n ±  0%        ~ (p=0.160 n=6)
FastRegexMatcher/.+foo.+-10                                 201.2n ± 1%   199.8n ±  1%   -0.72% (p=0.015 n=6)
FastRegexMatcher/(?s:.*)-10                                 46.12n ± 1%   46.27n ±  0%        ~ (p=0.784 n=6)
FastRegexMatcher/(?s:.+)-10                                 54.32n ± 1%   53.71n ±  0%   -1.10% (p=0.011 n=6)
FastRegexMatcher/(?s:^.*foo$)-10                            98.18n ± 1%   98.03n ±  0%        ~ (p=0.589 n=6)
FastRegexMatcher/(?i:foo)-10                                75.45n ± 1%   74.91n ±  0%        ~ (p=0.240 n=6)
FastRegexMatcher/(?i:(foo|bar))-10                          173.6n ± 1%   172.0n ±  0%   -0.92% (p=0.048 n=6)
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                    318.1n ± 1%   317.0n ±  1%        ~ (p=0.699 n=6)
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                     741.2n ± 0%   742.7n ±  0%        ~ (p=0.229 n=6)
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10        1.596µ ± 1%   1.588µ ±  1%        ~ (p=0.394 n=6)
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10             511.9n ± 1%   513.6n ±  0%        ~ (p=0.093 n=6)
FastRegexMatcher/^$-10                                      47.14n ± 1%   48.60n ±  1%   +3.11% (p=0.002 n=6)
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10         174.8n ± 1%   176.7n ±  1%   +1.12% (p=0.002 n=6)
FastRegexMatcher/10\.0\.(1|2)\.+-10                         71.01n ± 1%   70.58n ±  0%   -0.61% (p=0.015 n=6)
FastRegexMatcher/10\.0\.(1|2).+-10                          70.69n ± 1%   70.56n ±  0%   -0.19% (p=0.028 n=6)
FastRegexMatcher/((fo(bar))|.+foo)-10                       244.0n ± 1%   263.5n ±  0%   +7.99% (p=0.002 n=6)
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10        740.5n ± 2%   204.2n ±  6%  -72.42% (p=0.002 n=6)
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10       3033.5n ± 1%   217.5n ±  6%  -92.83% (p=0.002 n=6)
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10        1.587µ ± 2%   1.589µ ±  1%        ~ (p=0.561 n=6)
geomean                                                     925.9n        749.7n        -19.03%

                                                        │      before      │                  after                   │
                                                        │       B/op       │     B/op      vs base                    │
NewFastRegexMatcher/foo-10                                   3240.0 ± 0%       176.0 ± 0%   -94.57% (p=0.002 n=6)
NewFastRegexMatcher/^foo-10                                 3.766Ki ± 0%     3.797Ki ± 0%    +0.83% (p=0.002 n=6)
NewFastRegexMatcher/(foo|bar)-10                            5.781Ki ± 0%     5.875Ki ± 0%    +1.62% (p=0.002 n=6)
NewFastRegexMatcher/foo.*-10                                4.906Ki ± 0%     4.938Ki ± 0%    +0.64% (p=0.002 n=6)
NewFastRegexMatcher/.*foo-10                                4.953Ki ± 0%     4.984Ki ± 0%    +0.63% (p=0.002 n=6)
NewFastRegexMatcher/^.*foo$-10                              5.656Ki ± 0%     5.703Ki ± 0%    +0.83% (p=0.002 n=6)
NewFastRegexMatcher/^.+foo$-10                              5.711Ki ± 0%     5.750Ki ± 0%    +0.68% (p=0.002 n=6)
NewFastRegexMatcher/.*-10                                   3.102Ki ± 0%     3.133Ki ± 0%    +1.01% (p=0.002 n=6)
NewFastRegexMatcher/.+-10                                   3.086Ki ± 0%     3.102Ki ± 0%    +0.51% (p=0.002 n=6)
NewFastRegexMatcher/foo.+-10                                4.906Ki ± 0%     4.938Ki ± 0%    +0.64% (p=0.002 n=6)
NewFastRegexMatcher/.+foo-10                                4.977Ki ± 0%     5.016Ki ± 0%    +0.78% (p=0.002 n=6)
NewFastRegexMatcher/foo_.+-10                               5.000Ki ± 0%     5.031Ki ± 0%    +0.63% (p=0.002 n=6)
NewFastRegexMatcher/foo_.*-10                               5.000Ki ± 0%     5.031Ki ± 0%    +0.63% (p=0.002 n=6)
NewFastRegexMatcher/.*foo.*-10                              5.703Ki ± 0%     5.750Ki ± 0%    +0.82% (p=0.002 n=6)
NewFastRegexMatcher/.+foo.+-10                              5.727Ki ± 0%     5.766Ki ± 0%    +0.68% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.*)-10                              3.172Ki ± 0%     3.219Ki ± 0%    +1.48% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.+)-10                              3.164Ki ± 0%     3.211Ki ± 0%    +1.48% (p=0.002 n=6)
NewFastRegexMatcher/(?s:^.*foo$)-10                         5.797Ki ± 0%     5.859Ki ± 0%    +1.08% (p=0.002 n=6)
NewFastRegexMatcher/(?i:foo)-10                             3.625Ki ± 0%     3.672Ki ± 0%    +1.29% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo|bar))-10                       6.531Ki ± 0%     6.641Ki ± 0%    +1.67% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|bar))-10                 7.508Ki ± 0%     7.641Ki ± 0%    +1.77% (p=0.002 n=6)
NewFastRegexMatcher/^(?i:foo|oo)|(bar)$-10                  10.22Ki ± 0%     10.34Ki ± 0%    +1.22% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10     41.20Ki ± 0%     41.88Ki ± 0%    +1.65% (p=0.002 n=6)
NewFastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10          13.69Ki ± 0%     13.84Ki ± 0%    +1.08% (p=0.002 n=6)
NewFastRegexMatcher/^$-10                                   3.359Ki ± 0%     3.383Ki ± 0%    +0.70% (p=0.002 n=6)
NewFastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10      14.22Ki ± 0%     14.34Ki ± 0%    +0.82% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2)\.+-10                      6.164Ki ± 0%     6.273Ki ± 0%    +1.77% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2).+-10                       6.531Ki ± 0%     6.641Ki ± 0%    +1.67% (p=0.002 n=6)
NewFastRegexMatcher/((fo(bar))|.+foo)-10                    9.672Ki ± 0%     9.789Ki ± 0%    +1.21% (p=0.002 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10   248.823Ki ± 0%     4.734Ki ± 0%   -98.10% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10   4417.90Ki ± 0%     80.27Ki ± 0%   -98.18% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10     266.3Ki ± 0%     269.1Ki ± 0%    +1.04% (p=0.002 n=6)
FastRegexMatcher/foo-10                                       0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^foo-10                                      0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(foo|bar)-10                                 0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.*-10                                     0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo-10                                     0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.*foo$-10                                   0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.+foo$-10                                   0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*-10                                        0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+-10                                        0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.+-10                                     0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo-10                                     0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.+-10                                    0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.*-10                                    0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo.*-10                                   0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo.+-10                                   0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.*)-10                                   0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.+)-10                                   0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:^.*foo$)-10                              0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:foo)-10                                  0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo|bar))-10                            0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                      0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                       0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10          560.0 ± 0%       560.0 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10               0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^$-10                                        0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10           0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2)\.+-10                           0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2).+-10                            0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/((fo(bar))|.+foo)-10                         0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10          0.000 ± 0%       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10          1.000 ± 0%       0.000 ± 0%  -100.00% (p=0.002 n=6)
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10          560.0 ± 0%       560.0 ± 0%         ~ (p=1.000 n=6) ¹
geomean                                                                  ²                 ?                      ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

                                                        │      before      │                after                 │
                                                        │    allocs/op     │  allocs/op   vs base                 │
NewFastRegexMatcher/foo-10                                   53.000 ± 0%      3.000 ± 0%  -94.34% (p=0.002 n=6)
NewFastRegexMatcher/^foo-10                                   64.00 ± 0%      66.00 ± 0%   +3.12% (p=0.002 n=6)
NewFastRegexMatcher/(foo|bar)-10                              87.00 ± 0%      91.00 ± 0%   +4.60% (p=0.002 n=6)
NewFastRegexMatcher/foo.*-10                                  74.00 ± 0%      76.00 ± 0%   +2.70% (p=0.002 n=6)
NewFastRegexMatcher/.*foo-10                                  65.00 ± 0%      67.00 ± 0%   +3.08% (p=0.002 n=6)
NewFastRegexMatcher/^.*foo$-10                                72.00 ± 0%      74.00 ± 0%   +2.78% (p=0.002 n=6)
NewFastRegexMatcher/^.+foo$-10                                75.00 ± 0%      77.00 ± 0%   +2.67% (p=0.002 n=6)
NewFastRegexMatcher/.*-10                                     48.00 ± 0%      50.00 ± 0%   +4.17% (p=0.002 n=6)
NewFastRegexMatcher/.+-10                                     45.00 ± 0%      47.00 ± 0%   +4.44% (p=0.002 n=6)
NewFastRegexMatcher/foo.+-10                                  75.00 ± 0%      77.00 ± 0%   +2.67% (p=0.002 n=6)
NewFastRegexMatcher/.+foo-10                                  67.00 ± 0%      69.00 ± 0%   +2.99% (p=0.002 n=6)
NewFastRegexMatcher/foo_.+-10                                 77.00 ± 0%      79.00 ± 0%   +2.60% (p=0.002 n=6)
NewFastRegexMatcher/foo_.*-10                                 76.00 ± 0%      78.00 ± 0%   +2.63% (p=0.002 n=6)
NewFastRegexMatcher/.*foo.*-10                                72.00 ± 0%      74.00 ± 0%   +2.78% (p=0.002 n=6)
NewFastRegexMatcher/.+foo.+-10                                75.00 ± 0%      77.00 ± 0%   +2.67% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.*)-10                                48.00 ± 0%      50.00 ± 0%   +4.17% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.+)-10                                46.00 ± 0%      48.00 ± 0%   +4.35% (p=0.002 n=6)
NewFastRegexMatcher/(?s:^.*foo$)-10                           73.00 ± 0%      75.00 ± 0%   +2.74% (p=0.002 n=6)
NewFastRegexMatcher/(?i:foo)-10                               61.00 ± 0%      63.00 ± 0%   +3.28% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo|bar))-10                         105.0 ± 0%      109.0 ± 0%   +3.81% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|bar))-10                   135.0 ± 0%      139.0 ± 0%   +2.96% (p=0.002 n=6)
NewFastRegexMatcher/^(?i:foo|oo)|(bar)$-10                    133.0 ± 0%      137.0 ± 0%   +3.01% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10       428.0 ± 0%      433.0 ± 0%   +1.17% (p=0.002 n=6)
NewFastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10            147.0 ± 0%      151.0 ± 0%   +2.72% (p=0.002 n=6)
NewFastRegexMatcher/^$-10                                     47.00 ± 0%      49.00 ± 0%   +4.26% (p=0.002 n=6)
NewFastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10        178.0 ± 0%      182.0 ± 0%   +2.25% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2)\.+-10                        94.00 ± 0%      98.00 ± 0%   +4.26% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2).+-10                         107.0 ± 0%      111.0 ± 0%   +3.74% (p=0.002 n=6)
NewFastRegexMatcher/((fo(bar))|.+foo)-10                      112.0 ± 0%      116.0 ± 0%   +3.57% (p=0.002 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10    1228.000 ± 0%      7.000 ± 0%  -99.43% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10   30727.000 ± 0%      6.000 ± 0%  -99.98% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10      1.497k ± 0%     1.503k ± 0%   +0.40% (p=0.002 n=6)
FastRegexMatcher/foo-10                                       0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^foo-10                                      0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(foo|bar)-10                                 0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.*-10                                     0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo-10                                     0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.*foo$-10                                   0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.+foo$-10                                   0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*-10                                        0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+-10                                        0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.+-10                                     0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo-10                                     0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.+-10                                    0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.*-10                                    0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo.*-10                                   0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo.+-10                                   0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.*)-10                                   0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.+)-10                                   0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:^.*foo$)-10                              0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:foo)-10                                  0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo|bar))-10                            0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                      0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                       0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10          18.00 ± 0%      18.00 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10               0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^$-10                                        0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10           0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2)\.+-10                           0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2).+-10                            0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/((fo(bar))|.+foo)-10                         0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10          0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10          0.000 ± 0%      0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10          18.00 ± 0%      18.00 ± 0%        ~ (p=1.000 n=6) ¹
geomean                                                                  ²                -21.74%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

@CLAassistant
Copy link

CLAassistant commented Mar 29, 2023

CLA assistant check
All committers have signed the CLA.

@Logiraptor Logiraptor requested review from colega and pracucci March 29, 2023 23:47
@Logiraptor
Copy link
Contributor Author

Further testing:

I downloaded a dataset of 713287 real queries from the cell where this issue was discovered (Cell A), and 504496 queries from a shared cell where this issue is not noticeable (Cell B). I wrote a small program to parse the queries and throw away the result. Much of this time is spent reading the queries from disk or running GC, but nonetheless the results are promising:

cell timed section before after
Cell A total time 180.70s 91.27s
ParseExpr 24s 9.4s
Cell B total time 9.6s 8.7s
ParseExpr 1.2s 0.7s

I'm cautiously optimistic that the small increases in cost don't manifest in real queries.

Furthermore, I believe there is still significant improvements to be made by supporting case insensitive matches via the prefix trie. Cell A has 79% of queries making use of (?i: somewhere in queries, compared to 1% in Cell B. I don't think this is too difficult to support, so I will try that next.

@pracucci
Copy link
Collaborator

Furthermore, I believe there is still significant improvements to be made by supporting case insensitive matches via the prefix trie.

I would defer it to a follow up PR.

@pracucci
Copy link
Collaborator

pracucci commented Mar 30, 2023

I just pushed a commit to fix fuzzy test with the fuzzy regexp: 0590a86

@pracucci
Copy link
Collaborator

pracucci commented Mar 30, 2023

I was wondering if we really need a trie, or a map is just good enough. So I picked this PR and implemented your proposed optimization just using a map (specifically using equalMultiStringMatcher).

This is the FastRegexMatcher benchmark comparing this PR vs map:

name                                                  old time/op    new time/op    delta
FastRegexMatcher/foo-12                                 77.1ns ± 1%    74.3ns ± 0%   -3.61%  (p=0.020 n=3+3)
FastRegexMatcher/^foo-12                                64.2ns ± 2%    63.9ns ± 1%     ~     (p=0.682 n=3+3)
FastRegexMatcher/(foo|bar)-12                           74.2ns ± 3%    74.7ns ± 1%     ~     (p=0.666 n=3+3)
FastRegexMatcher/foo.*-12                                130ns ± 1%     131ns ± 3%     ~     (p=0.828 n=3+3)
FastRegexMatcher/.*foo-12                                154ns ± 2%     150ns ± 3%     ~     (p=0.277 n=3+3)
FastRegexMatcher/^.*foo$-12                              155ns ± 2%     148ns ± 3%     ~     (p=0.071 n=3+3)
FastRegexMatcher/^.+foo$-12                              151ns ± 1%     148ns ± 1%   -2.14%  (p=0.043 n=3+3)
FastRegexMatcher/.*-12                                   134ns ± 3%     129ns ± 1%     ~     (p=0.137 n=3+3)
FastRegexMatcher/.+-12                                   135ns ± 4%     127ns ± 4%     ~     (p=0.082 n=3+3)
FastRegexMatcher/foo.+-12                                130ns ± 4%     131ns ± 4%     ~     (p=0.865 n=3+3)
FastRegexMatcher/.+foo-12                                155ns ± 2%     141ns ± 2%   -8.46%  (p=0.002 n=3+3)
FastRegexMatcher/foo_.+-12                               113ns ± 1%     120ns ± 2%   +6.28%  (p=0.013 n=3+3)
FastRegexMatcher/foo_.*-12                               117ns ± 3%     116ns ± 3%     ~     (p=0.680 n=3+3)
FastRegexMatcher/.*foo.*-12                              279ns ± 3%     272ns ± 2%     ~     (p=0.235 n=3+3)
FastRegexMatcher/.+foo.+-12                              291ns ± 1%     282ns ± 2%     ~     (p=0.063 n=3+3)
FastRegexMatcher/(?s:.*)-12                             62.4ns ± 1%    60.2ns ± 3%     ~     (p=0.100 n=3+3)
FastRegexMatcher/(?s:.+)-12                             78.2ns ± 3%    78.3ns ± 2%     ~     (p=0.953 n=3+3)
FastRegexMatcher/(?s:^.*foo$)-12                         144ns ± 3%     140ns ± 2%     ~     (p=0.213 n=3+3)
FastRegexMatcher/(?i:foo)-12                             108ns ± 1%     108ns ± 1%     ~     (p=0.603 n=3+3)
FastRegexMatcher/(?i:(foo|bar))-12                       252ns ± 4%     233ns ± 2%   -7.53%  (p=0.048 n=3+3)
FastRegexMatcher/(?i:(foo1|foo2|bar))-12                 420ns ± 5%     412ns ± 0%     ~     (p=0.505 n=3+3)
FastRegexMatcher/^(?i:foo|oo)|(bar)$-12                 1.05µs ± 3%    1.01µs ± 4%     ~     (p=0.212 n=3+3)
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-12    1.95µs ± 1%    1.97µs ± 7%     ~     (p=0.729 n=3+3)
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-12          693ns ± 3%     666ns ± 1%     ~     (p=0.131 n=3+3)
FastRegexMatcher/^$-12                                  63.8ns ± 1%    62.7ns ± 1%     ~     (p=0.148 n=3+3)
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-12      210ns ± 2%     215ns ± 1%     ~     (p=0.168 n=3+3)
FastRegexMatcher/10\.0\.(1|2)\.+-12                      114ns ± 6%     116ns ± 1%     ~     (p=0.560 n=3+3)
FastRegexMatcher/10\.0\.(1|2).+-12                       111ns ± 3%     116ns ± 1%     ~     (p=0.102 n=3+3)
FastRegexMatcher/((fo(bar))|.+foo)-12                    318ns ± 2%     316ns ± 5%     ~     (p=0.791 n=3+3)
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-12     414ns ± 1%     311ns ± 3%  -24.80%  (p=0.001 n=3+3)
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-12     305ns ± 2%     304ns ± 3%     ~     (p=0.807 n=3+3)
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-12    1.96µs ± 3%    1.92µs ± 0%     ~     (p=0.258 n=3+3)

Maybe it's something you want to explore more.

Also be aware of optimizeEqualStringMatchersThreshold. Below that number may have sense replacing the map with just a slice (to be benchmarked).

model/labels/regexp_test.go Outdated Show resolved Hide resolved
model/labels/regexp.go Outdated Show resolved Hide resolved
model/labels/regexp.go Outdated Show resolved Hide resolved
model/labels/regexp.go Outdated Show resolved Hide resolved
model/labels/regexp.go Outdated Show resolved Hide resolved
model/labels/regexp.go Show resolved Hide resolved
model/labels/trie_test.go Outdated Show resolved Hide resolved
model/labels/regexp.go Outdated Show resolved Hide resolved
@pracucci
Copy link
Collaborator

I was wondering if we really need a trie, or a map is just good enough. So I picked this PR and implemented your proposed optimization just using a map (specifically using equalMultiStringMatcher).

About this ☝️ : in the meanwhile I was exploring another optimization, but didn't get much benefit so I'm not going to open a PR. However, you may want to look at the changes I did to equalMultiStringMatcher there, if you consider replacing the trie with a simple map: https://github.com/grafana/mimir-prometheus/compare/do-not-limit-optimization-because-of-max-set-matches

@Logiraptor
Copy link
Contributor Author

Logiraptor commented Mar 30, 2023

Based on @pracucci's feedback I profiled an implementation with a map and also with a slice / map depending on input size. The results favor using a slice / map, so I've replaced the trie.

Full Benchmark Results
goos: darwin
goarch: arm64
pkg: github.com/prometheus/prometheus/model/labels
                                                        │    before     │                trie                 │                 map                 │               slicemap               │
                                                        │    sec/op     │    sec/op     vs base               │    sec/op     vs base               │    sec/op      vs base               │
NewFastRegexMatcher/foo-10                                 1978.0n ± 2%    238.8n ± 1%  -87.92% (p=0.002 n=6)   169.1n ±  1%  -91.45% (p=0.002 n=6)    131.0n ±  6%  -93.38% (p=0.002 n=6)
NewFastRegexMatcher/^foo-10                                 2.396µ ± 2%    2.447µ ± 3%   +2.15% (p=0.002 n=6)   2.422µ ±  7%   +1.11% (p=0.019 n=6)    2.439µ ± 10%   +1.82% (p=0.004 n=6)
NewFastRegexMatcher/(foo|bar)-10                            3.753µ ± 1%    3.953µ ± 3%   +5.34% (p=0.002 n=6)   3.821µ ±  4%   +1.81% (p=0.002 n=6)    3.846µ ±  5%   +2.48% (p=0.002 n=6)
NewFastRegexMatcher/foo.*-10                                2.966µ ± 2%    3.093µ ± 2%   +4.30% (p=0.002 n=6)   3.006µ ±  6%   +1.38% (p=0.026 n=6)    3.023µ ±  1%   +1.96% (p=0.004 n=6)
NewFastRegexMatcher/.*foo-10                                2.768µ ± 2%    2.930µ ± 6%   +5.87% (p=0.002 n=6)   2.797µ ±  2%        ~ (p=0.132 n=6)    2.907µ ± 10%   +5.04% (p=0.004 n=6)
NewFastRegexMatcher/^.*foo$-10                              3.168µ ± 2%    3.340µ ± 2%   +5.45% (p=0.002 n=6)   3.216µ ±  0%        ~ (p=0.061 n=6)    3.239µ ±  3%   +2.26% (p=0.004 n=6)
NewFastRegexMatcher/^.+foo$-10                              3.278µ ± 2%    3.376µ ± 2%   +2.99% (p=0.002 n=6)   3.311µ ±  1%        ~ (p=0.331 n=6)    3.305µ ±  2%        ~ (p=0.180 n=6)
NewFastRegexMatcher/.*-10                                   1.914µ ± 2%    1.990µ ± 1%   +4.02% (p=0.002 n=6)   1.943µ ±  3%   +1.54% (p=0.009 n=6)    1.960µ ±  8%   +2.40% (p=0.002 n=6)
NewFastRegexMatcher/.+-10                                   1.844µ ± 4%    1.910µ ± 2%   +3.58% (p=0.009 n=6)   1.868µ ±  1%        ~ (p=0.165 n=6)    1.987µ ±  7%   +7.75% (p=0.002 n=6)
NewFastRegexMatcher/foo.+-10                                3.043µ ± 1%    3.146µ ± 2%   +3.38% (p=0.002 n=6)   3.079µ ±  1%   +1.17% (p=0.030 n=6)    3.256µ ±  6%   +7.00% (p=0.002 n=6)
NewFastRegexMatcher/.+foo-10                                2.843µ ± 3%    3.005µ ± 2%   +5.72% (p=0.002 n=6)   2.895µ ±  4%        ~ (p=0.180 n=6)    2.953µ ±  6%   +3.89% (p=0.004 n=6)
NewFastRegexMatcher/foo_.+-10                               3.212µ ± 2%    3.403µ ± 2%   +5.95% (p=0.002 n=6)   3.249µ ±  3%        ~ (p=0.065 n=6)    3.283µ ±  8%   +2.21% (p=0.002 n=6)
NewFastRegexMatcher/foo_.*-10                               3.201µ ± 2%    3.315µ ± 3%   +3.56% (p=0.002 n=6)   3.224µ ±  1%        ~ (p=0.145 n=6)    3.333µ ± 10%   +4.12% (p=0.004 n=6)
NewFastRegexMatcher/.*foo.*-10                              3.285µ ± 2%    3.411µ ± 2%   +3.82% (p=0.002 n=6)   3.330µ ±  0%   +1.35% (p=0.009 n=6)    3.349µ ±  5%   +1.93% (p=0.002 n=6)
NewFastRegexMatcher/.+foo.+-10                              3.319µ ± 2%    3.489µ ± 2%   +5.12% (p=0.002 n=6)   3.391µ ±  1%        ~ (p=0.071 n=6)    3.495µ ±  7%   +5.30% (p=0.009 n=6)
NewFastRegexMatcher/(?s:.*)-10                              1.991µ ± 2%    2.103µ ± 1%   +5.60% (p=0.002 n=6)   2.077µ ±  2%   +4.29% (p=0.002 n=6)    2.043µ ±  4%   +2.61% (p=0.004 n=6)
NewFastRegexMatcher/(?s:.+)-10                              1.950µ ± 1%    2.036µ ± 1%   +4.38% (p=0.002 n=6)   1.995µ ±  0%   +2.28% (p=0.002 n=6)    1.994µ ±  3%   +2.26% (p=0.002 n=6)
NewFastRegexMatcher/(?s:^.*foo$)-10                         3.370µ ± 2%    3.490µ ± 1%   +3.56% (p=0.002 n=6)   3.442µ ±  1%        ~ (p=0.065 n=6)    3.401µ ±  1%        ~ (p=0.394 n=6)
NewFastRegexMatcher/(?i:foo)-10                             2.510µ ± 2%    2.668µ ± 2%   +6.32% (p=0.002 n=6)   2.585µ ±  2%   +2.99% (p=0.002 n=6)    2.559µ ±  8%   +1.97% (p=0.015 n=6)
NewFastRegexMatcher/(?i:(foo|bar))-10                       4.660µ ± 1%    4.792µ ± 1%   +2.82% (p=0.002 n=6)   4.666µ ±  1%        ~ (p=0.853 n=6)    4.678µ ±  3%        ~ (p=0.420 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|bar))-10                 5.967µ ± 2%    6.140µ ± 1%   +2.91% (p=0.002 n=6)   6.011µ ±  1%        ~ (p=0.132 n=6)    6.208µ ±  3%   +4.04% (p=0.002 n=6)
NewFastRegexMatcher/^(?i:foo|oo)|(bar)$-10                  6.580µ ± 2%    6.735µ ± 2%   +2.36% (p=0.015 n=6)   6.602µ ±  1%        ~ (p=0.667 n=6)    6.605µ ±  1%        ~ (p=0.699 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10     27.83µ ± 2%    27.74µ ± 2%        ~ (p=0.699 n=6)   27.68µ ±  2%        ~ (p=0.485 n=6)    28.84µ ±  5%   +3.66% (p=0.026 n=6)
NewFastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10          8.447µ ± 2%    8.663µ ± 2%   +2.56% (p=0.004 n=6)   8.422µ ±  1%        ~ (p=0.818 n=6)    8.762µ ±  4%   +3.74% (p=0.002 n=6)
NewFastRegexMatcher/^$-10                                   1.912µ ± 3%    2.006µ ± 6%   +4.92% (p=0.002 n=6)   1.988µ ±  3%   +3.97% (p=0.002 n=6)    2.054µ ±  3%   +7.40% (p=0.002 n=6)
NewFastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10      9.039µ ± 2%    9.285µ ± 2%   +2.72% (p=0.006 n=6)   9.023µ ±  0%        ~ (p=1.000 n=6)    9.165µ ±  4%   +1.39% (p=0.041 n=6)
NewFastRegexMatcher/10\.0\.(1|2)\.+-10                      4.345µ ± 1%    4.470µ ± 1%   +2.88% (p=0.002 n=6)   4.394µ ±  4%   +1.13% (p=0.030 n=6)    4.547µ ±  3%   +4.66% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2).+-10                       4.692µ ± 2%    4.803µ ± 2%   +2.38% (p=0.002 n=6)   4.760µ ±  1%   +1.46% (p=0.037 n=6)    4.832µ ±  2%   +2.98% (p=0.009 n=6)
NewFastRegexMatcher/((fo(bar))|.+foo)-10                    5.782µ ± 3%    5.906µ ± 1%   +2.14% (p=0.028 n=6)   5.790µ ±  0%        ~ (p=0.937 n=6)    5.974µ ±  3%   +3.31% (p=0.026 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10   139.687µ ± 2%   38.748µ ± 1%  -72.26% (p=0.002 n=6)   6.024µ ±  1%  -95.69% (p=0.002 n=6)    7.498µ ±  3%  -94.63% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10    5726.0µ ± 1%    707.9µ ± 2%  -87.64% (p=0.002 n=6)   183.0µ ±  1%  -96.80% (p=0.002 n=6)    192.0µ ±  3%  -96.65% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10     164.1µ ± 2%    162.1µ ± 1%        ~ (p=0.180 n=6)   161.9µ ±  0%   -1.32% (p=0.026 n=6)    168.5µ ±  9%   +2.66% (p=0.041 n=6)
FastRegexMatcher/foo-10                                     53.39n ± 5%    57.74n ± 1%   +8.14% (p=0.002 n=6)   57.65n ±  1%   +7.98% (p=0.002 n=6)    58.91n ±  2%  +10.34% (p=0.002 n=6)
FastRegexMatcher/^foo-10                                    52.95n ± 4%    53.72n ± 1%        ~ (p=0.132 n=6)   53.03n ±  2%        ~ (p=0.818 n=6)    54.49n ±  2%   +2.92% (p=0.041 n=6)
FastRegexMatcher/(foo|bar)-10                               59.55n ± 1%    60.99n ± 1%   +2.44% (p=0.002 n=6)   59.37n ±  0%        ~ (p=0.221 n=6)    59.66n ±  2%        ~ (p=0.132 n=6)
FastRegexMatcher/foo.*-10                                   88.07n ± 1%    89.17n ± 2%   +1.25% (p=0.004 n=6)   87.64n ±  1%        ~ (p=0.167 n=6)    89.33n ±  2%   +1.43% (p=0.004 n=6)
FastRegexMatcher/.*foo-10                                   101.7n ± 1%    102.2n ± 1%        ~ (p=0.130 n=6)   100.6n ±  0%   -1.13% (p=0.002 n=6)    113.7n ±  1%  +11.74% (p=0.002 n=6)
FastRegexMatcher/^.*foo$-10                                 101.4n ± 1%    103.0n ± 1%   +1.53% (p=0.006 n=6)   100.6n ±  0%   -0.79% (p=0.002 n=6)    113.4n ±  1%  +11.83% (p=0.002 n=6)
FastRegexMatcher/^.+foo$-10                                 101.9n ± 1%    103.2n ± 2%   +1.23% (p=0.015 n=6)   101.1n ±  0%   -0.74% (p=0.039 n=6)    113.3n ±  1%  +11.24% (p=0.002 n=6)
FastRegexMatcher/.*-10                                      76.70n ± 1%    84.89n ± 1%  +10.68% (p=0.002 n=6)   86.68n ±  0%  +13.02% (p=0.002 n=6)    81.56n ±  1%   +6.35% (p=0.002 n=6)
FastRegexMatcher/.+-10                                      80.77n ± 0%    88.02n ± 1%   +8.98% (p=0.002 n=6)   91.60n ±  1%  +13.41% (p=0.002 n=6)    82.11n ±  1%   +1.65% (p=0.002 n=6)
FastRegexMatcher/foo.+-10                                   88.32n ± 1%    89.07n ± 1%        ~ (p=0.121 n=6)   88.06n ±  0%   -0.29% (p=0.022 n=6)    89.41n ±  1%   +1.23% (p=0.041 n=6)
FastRegexMatcher/.+foo-10                                   102.0n ± 1%    102.4n ± 1%        ~ (p=0.141 n=6)   101.2n ±  0%   -0.69% (p=0.002 n=6)    114.0n ±  2%  +11.77% (p=0.002 n=6)
FastRegexMatcher/foo_.+-10                                  70.77n ± 0%    71.07n ± 1%   +0.42% (p=0.024 n=6)   70.30n ±  0%   -0.66% (p=0.009 n=6)    71.40n ±  2%   +0.89% (p=0.011 n=6)
FastRegexMatcher/foo_.*-10                                  70.76n ± 2%    71.12n ± 1%        ~ (p=0.240 n=6)   70.35n ±  0%   -0.58% (p=0.006 n=6)    70.97n ±  1%        ~ (p=0.937 n=6)
FastRegexMatcher/.*foo.*-10                                 189.1n ± 2%    191.6n ± 1%   +1.35% (p=0.039 n=6)   189.5n ±  2%        ~ (p=0.082 n=6)    193.1n ±  2%   +2.14% (p=0.004 n=6)
FastRegexMatcher/.+foo.+-10                                 201.2n ± 1%    202.8n ± 0%   +0.82% (p=0.041 n=6)   199.8n ±  0%   -0.70% (p=0.009 n=6)    201.5n ±  1%        ~ (p=1.000 n=6)
FastRegexMatcher/(?s:.*)-10                                 46.12n ± 1%    46.70n ± 1%   +1.25% (p=0.009 n=6)   45.80n ±  1%        ~ (p=0.288 n=6)    46.31n ±  1%        ~ (p=0.310 n=6)
FastRegexMatcher/(?s:.+)-10                                 54.32n ± 1%    54.11n ± 1%        ~ (p=0.310 n=6)   53.89n ±  0%        ~ (p=0.132 n=6)    53.51n ±  1%   -1.47% (p=0.013 n=6)
FastRegexMatcher/(?s:^.*foo$)-10                            98.18n ± 1%    99.52n ± 1%        ~ (p=0.065 n=6)   98.01n ±  0%        ~ (p=0.617 n=6)   110.00n ±  1%  +12.04% (p=0.002 n=6)
FastRegexMatcher/(?i:foo)-10                                75.45n ± 1%    75.63n ± 1%        ~ (p=0.102 n=6)   78.38n ±  0%   +3.88% (p=0.002 n=6)    76.23n ±  2%   +1.04% (p=0.026 n=6)
FastRegexMatcher/(?i:(foo|bar))-10                          173.6n ± 1%    173.3n ± 1%        ~ (p=0.675 n=6)   180.3n ±  3%   +3.86% (p=0.004 n=6)    172.0n ±  2%        ~ (p=0.128 n=6)
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                    318.1n ± 1%    318.2n ± 1%        ~ (p=0.818 n=6)   324.1n ±  1%   +1.89% (p=0.002 n=6)    320.9n ±  2%        ~ (p=0.121 n=6)
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                     741.2n ± 0%    751.5n ± 1%   +1.38% (p=0.002 n=6)   750.7n ±  2%   +1.27% (p=0.002 n=6)    757.2n ±  2%   +2.16% (p=0.002 n=6)
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10        1.596µ ± 1%    1.610µ ± 2%        ~ (p=0.223 n=6)   1.639µ ±  2%   +2.69% (p=0.009 n=6)    1.606µ ±  3%        ~ (p=0.331 n=6)
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10             511.9n ± 1%    527.5n ± 1%   +3.04% (p=0.002 n=6)   522.2n ±  2%   +2.01% (p=0.002 n=6)    533.7n ±  3%   +4.25% (p=0.002 n=6)
FastRegexMatcher/^$-10                                      47.14n ± 1%    48.30n ± 2%   +2.47% (p=0.002 n=6)   47.83n ±  2%   +1.49% (p=0.017 n=6)    47.97n ±  2%   +1.77% (p=0.002 n=6)
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10         174.8n ± 1%    178.7n ± 1%   +2.26% (p=0.002 n=6)   177.5n ±  1%   +1.57% (p=0.002 n=6)    175.1n ±  1%        ~ (p=0.775 n=6)
FastRegexMatcher/10\.0\.(1|2)\.+-10                         71.01n ± 1%    71.23n ± 1%        ~ (p=0.394 n=6)   71.20n ±  2%        ~ (p=0.589 n=6)    70.57n ±  0%   -0.62% (p=0.013 n=6)
FastRegexMatcher/10\.0\.(1|2).+-10                          70.69n ± 1%    71.09n ± 1%        ~ (p=0.093 n=6)   71.32n ±  2%   +0.90% (p=0.041 n=6)    70.58n ±  0%        ~ (p=0.225 n=6)
FastRegexMatcher/((fo(bar))|.+foo)-10                       244.0n ± 1%    249.1n ± 1%   +2.09% (p=0.002 n=6)   254.9n ±  0%   +4.47% (p=0.002 n=6)    242.8n ±  0%        ~ (p=0.119 n=6)
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10        740.5n ± 2%    483.6n ± 1%  -34.70% (p=0.002 n=6)   215.3n ± 11%  -70.93% (p=0.002 n=6)    210.0n ± 13%  -71.64% (p=0.002 n=6)
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10       3033.5n ± 1%    363.1n ± 2%  -88.03% (p=0.002 n=6)   217.7n ±  9%  -92.82% (p=0.002 n=6)    223.2n ± 11%  -92.64% (p=0.002 n=6)
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10        1.587µ ± 2%    1.617µ ± 1%   +1.89% (p=0.045 n=6)   1.658µ ±  2%   +4.44% (p=0.002 n=6)    1.589µ ±  1%        ~ (p=0.818 n=6)
geomean                                                     925.9n         837.2n        -9.58%                 767.3n        -17.13%                  778.3n        -15.94%

                                                        │      before      │                   trie                    │                   map                    │                 slicemap                 │
                                                        │       B/op       │     B/op       vs base                    │     B/op      vs base                    │     B/op      vs base                    │
NewFastRegexMatcher/foo-10                                   3240.0 ± 0%        328.0 ± 0%   -89.88% (p=0.002 n=6)         384.0 ± 0%   -88.15% (p=0.002 n=6)         240.0 ± 0%   -92.59% (p=0.002 n=6)
NewFastRegexMatcher/^foo-10                                 3.766Ki ± 0%      3.828Ki ± 0%    +1.66% (p=0.002 n=6)       3.859Ki ± 0%    +2.49% (p=0.002 n=6)       3.844Ki ± 0%    +2.07% (p=0.002 n=6)
NewFastRegexMatcher/(foo|bar)-10                            5.781Ki ± 0%      5.844Ki ± 0%    +1.08% (p=0.002 n=6)       5.875Ki ± 0%    +1.62% (p=0.002 n=6)       5.859Ki ± 0%    +1.35% (p=0.002 n=6)
NewFastRegexMatcher/foo.*-10                                4.906Ki ± 0%      4.969Ki ± 0%    +1.27% (p=0.002 n=6)       5.000Ki ± 0%    +1.91% (p=0.002 n=6)       4.984Ki ± 0%    +1.59% (p=0.002 n=6)
NewFastRegexMatcher/.*foo-10                                4.953Ki ± 0%      5.016Ki ± 0%    +1.26% (p=0.002 n=6)       5.047Ki ± 0%    +1.89% (p=0.002 n=6)       5.031Ki ± 0%    +1.58% (p=0.002 n=6)
NewFastRegexMatcher/^.*foo$-10                              5.656Ki ± 0%      5.734Ki ± 0%    +1.38% (p=0.002 n=6)       5.766Ki ± 0%    +1.93% (p=0.002 n=6)       5.750Ki ± 0%    +1.66% (p=0.002 n=6)
NewFastRegexMatcher/^.+foo$-10                              5.711Ki ± 0%      5.781Ki ± 0%    +1.23% (p=0.002 n=6)       5.812Ki ± 0%    +1.78% (p=0.002 n=6)       5.797Ki ± 0%    +1.50% (p=0.002 n=6)
NewFastRegexMatcher/.*-10                                   3.102Ki ± 0%      3.164Ki ± 0%    +2.02% (p=0.002 n=6)       3.195Ki ± 0%    +3.02% (p=0.002 n=6)       3.180Ki ± 0%    +2.52% (p=0.002 n=6)
NewFastRegexMatcher/.+-10                                   3.086Ki ± 0%      3.133Ki ± 0%    +1.52% (p=0.002 n=6)       3.164Ki ± 0%    +2.53% (p=0.002 n=6)       3.148Ki ± 0%    +2.03% (p=0.002 n=6)
NewFastRegexMatcher/foo.+-10                                4.906Ki ± 0%      4.969Ki ± 0%    +1.27% (p=0.002 n=6)       5.000Ki ± 0%    +1.91% (p=0.002 n=6)       4.984Ki ± 0%    +1.59% (p=0.002 n=6)
NewFastRegexMatcher/.+foo-10                                4.977Ki ± 0%      5.047Ki ± 0%    +1.41% (p=0.002 n=6)       5.078Ki ± 0%    +2.04% (p=0.002 n=6)       5.062Ki ± 0%    +1.73% (p=0.002 n=6)
NewFastRegexMatcher/foo_.+-10                               5.000Ki ± 0%      5.062Ki ± 0%    +1.25% (p=0.002 n=6)       5.094Ki ± 0%    +1.88% (p=0.002 n=6)       5.078Ki ± 0%    +1.56% (p=0.002 n=6)
NewFastRegexMatcher/foo_.*-10                               5.000Ki ± 0%      5.062Ki ± 0%    +1.25% (p=0.002 n=6)       5.094Ki ± 0%    +1.88% (p=0.002 n=6)       5.078Ki ± 0%    +1.56% (p=0.002 n=6)
NewFastRegexMatcher/.*foo.*-10                              5.703Ki ± 0%      5.781Ki ± 0%    +1.37% (p=0.002 n=6)       5.812Ki ± 0%    +1.92% (p=0.002 n=6)       5.797Ki ± 0%    +1.64% (p=0.002 n=6)
NewFastRegexMatcher/.+foo.+-10                              5.727Ki ± 0%      5.797Ki ± 0%    +1.23% (p=0.002 n=6)       5.828Ki ± 0%    +1.77% (p=0.002 n=6)       5.812Ki ± 0%    +1.50% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.*)-10                              3.172Ki ± 0%      3.250Ki ± 0%    +2.46% (p=0.002 n=6)       3.281Ki ± 0%    +3.45% (p=0.002 n=6)       3.266Ki ± 0%    +2.96% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.+)-10                              3.164Ki ± 0%      3.242Ki ± 0%    +2.47% (p=0.002 n=6)       3.273Ki ± 0%    +3.46% (p=0.002 n=6)       3.258Ki ± 0%    +2.96% (p=0.002 n=6)
NewFastRegexMatcher/(?s:^.*foo$)-10                         5.797Ki ± 0%      5.891Ki ± 0%    +1.62% (p=0.002 n=6)       5.922Ki ± 0%    +2.16% (p=0.002 n=6)       5.906Ki ± 0%    +1.89% (p=0.002 n=6)
NewFastRegexMatcher/(?i:foo)-10                             3.625Ki ± 0%      3.703Ki ± 0%    +2.16% (p=0.002 n=6)       3.734Ki ± 0%    +3.02% (p=0.002 n=6)       3.719Ki ± 0%    +2.59% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo|bar))-10                       6.531Ki ± 0%      6.609Ki ± 0%    +1.20% (p=0.002 n=6)       6.641Ki ± 0%    +1.67% (p=0.002 n=6)       6.625Ki ± 0%    +1.44% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|bar))-10                 7.508Ki ± 0%      7.594Ki ± 0%    +1.14% (p=0.002 n=6)       7.625Ki ± 0%    +1.56% (p=0.002 n=6)       7.609Ki ± 0%    +1.35% (p=0.002 n=6)
NewFastRegexMatcher/^(?i:foo|oo)|(bar)$-10                  10.22Ki ± 0%      10.30Ki ± 0%    +0.76% (p=0.002 n=6)       10.33Ki ± 0%    +1.07% (p=0.002 n=6)       10.31Ki ± 0%    +0.92% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10     41.20Ki ± 0%      41.20Ki ± 0%    +0.02% (p=0.002 n=6)       41.31Ki ± 0%    +0.28% (p=0.002 n=6)       41.81Ki ± 0%    +1.50% (p=0.002 n=6)
NewFastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10          13.69Ki ± 0%      13.77Ki ± 0%    +0.63% (p=0.002 n=6)       13.80Ki ± 0%    +0.86% (p=0.002 n=6)       13.79Ki ± 0%    +0.74% (p=0.002 n=6)
NewFastRegexMatcher/^$-10                                   3.359Ki ± 0%      3.414Ki ± 0%    +1.63% (p=0.002 n=6)       3.445Ki ± 0%    +2.56% (p=0.002 n=6)       3.430Ki ± 0%    +2.09% (p=0.002 n=6)
NewFastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10      14.22Ki ± 0%      14.30Ki ± 0%    +0.60% (p=0.002 n=6)       14.34Ki ± 0%    +0.82% (p=0.002 n=6)       14.32Ki ± 0%    +0.71% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2)\.+-10                      6.164Ki ± 0%      6.242Ki ± 0%    +1.27% (p=0.002 n=6)       6.273Ki ± 0%    +1.77% (p=0.002 n=6)       6.258Ki ± 0%    +1.52% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2).+-10                       6.531Ki ± 0%      6.609Ki ± 0%    +1.20% (p=0.002 n=6)       6.641Ki ± 0%    +1.67% (p=0.002 n=6)       6.625Ki ± 0%    +1.44% (p=0.002 n=6)
NewFastRegexMatcher/((fo(bar))|.+foo)-10                    9.672Ki ± 0%      9.758Ki ± 0%    +0.89% (p=0.002 n=6)       9.789Ki ± 0%    +1.21% (p=0.002 n=6)       9.773Ki ± 0%    +1.05% (p=0.002 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10   248.823Ki ± 0%     30.414Ki ± 0%   -87.78% (p=0.002 n=6)       5.453Ki ± 0%   -97.81% (p=0.002 n=6)       7.259Ki ± 0%   -97.08% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10    4417.9Ki ± 0%      291.2Ki ± 0%   -93.41% (p=0.002 n=6)       167.0Ki ± 0%   -96.22% (p=0.002 n=6)       167.0Ki ± 0%   -96.22% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10     266.3Ki ± 0%      265.7Ki ± 0%    -0.26% (p=0.002 n=6)       266.5Ki ± 0%    +0.05% (p=0.002 n=6)       269.0Ki ± 0%    +0.99% (p=0.002 n=6)
FastRegexMatcher/foo-10                                       0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^foo-10                                      0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(foo|bar)-10                                 0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.*-10                                     0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo-10                                     0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.*foo$-10                                   0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.+foo$-10                                   0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*-10                                        0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+-10                                        0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.+-10                                     0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo-10                                     0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.+-10                                    0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.*-10                                    0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo.*-10                                   0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo.+-10                                   0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.*)-10                                   0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.+)-10                                   0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:^.*foo$)-10                              0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:foo)-10                                  0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo|bar))-10                            0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                      0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                       0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10          560.0 ± 0%        560.0 ± 0%         ~ (p=1.000 n=6) ¹       560.0 ± 0%         ~ (p=1.000 n=6) ¹       560.0 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10               0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/^$-10                                        0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10           0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2)\.+-10                           0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2).+-10                            0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/((fo(bar))|.+foo)-10                         0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10          0.000 ± 0%        0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹       0.000 ± 0%         ~ (p=1.000 n=6) ¹
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10          1.000 ± 0%        0.000 ± 0%  -100.00% (p=0.002 n=6)         0.000 ± 0%  -100.00% (p=0.002 n=6)         0.000 ± 0%  -100.00% (p=0.002 n=6)
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10          560.0 ± 0%        560.0 ± 0%         ~ (p=1.000 n=6) ¹       560.0 ± 0%         ~ (p=1.000 n=6) ¹       560.0 ± 0%         ~ (p=1.000 n=6) ¹
geomean                                                                  ²                  ?                      ² ³                 ?                      ² ³                 ?                      ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

                                                        │     before      │                  trie                  │                 map                  │               slicemap               │
                                                        │    allocs/op    │   allocs/op    vs base                 │  allocs/op   vs base                 │  allocs/op   vs base                 │
NewFastRegexMatcher/foo-10                                  53.000 ± 0%       10.000 ± 0%  -81.13% (p=0.002 n=6)      6.000 ± 0%  -88.68% (p=0.002 n=6)      5.000 ± 0%  -90.57% (p=0.002 n=6)
NewFastRegexMatcher/^foo-10                                  64.00 ± 0%        67.00 ± 0%   +4.69% (p=0.002 n=6)      68.00 ± 0%   +6.25% (p=0.002 n=6)      67.00 ± 0%   +4.69% (p=0.002 n=6)
NewFastRegexMatcher/(foo|bar)-10                             87.00 ± 0%        90.00 ± 0%   +3.45% (p=0.002 n=6)      91.00 ± 0%   +4.60% (p=0.002 n=6)      90.00 ± 0%   +3.45% (p=0.002 n=6)
NewFastRegexMatcher/foo.*-10                                 74.00 ± 0%        77.00 ± 0%   +4.05% (p=0.002 n=6)      78.00 ± 0%   +5.41% (p=0.002 n=6)      77.00 ± 0%   +4.05% (p=0.002 n=6)
NewFastRegexMatcher/.*foo-10                                 65.00 ± 0%        68.00 ± 0%   +4.62% (p=0.002 n=6)      69.00 ± 0%   +6.15% (p=0.002 n=6)      68.00 ± 0%   +4.62% (p=0.002 n=6)
NewFastRegexMatcher/^.*foo$-10                               72.00 ± 0%        75.00 ± 0%   +4.17% (p=0.002 n=6)      76.00 ± 0%   +5.56% (p=0.002 n=6)      75.00 ± 0%   +4.17% (p=0.002 n=6)
NewFastRegexMatcher/^.+foo$-10                               75.00 ± 0%        78.00 ± 0%   +4.00% (p=0.002 n=6)      79.00 ± 0%   +5.33% (p=0.002 n=6)      78.00 ± 0%   +4.00% (p=0.002 n=6)
NewFastRegexMatcher/.*-10                                    48.00 ± 0%        51.00 ± 0%   +6.25% (p=0.002 n=6)      52.00 ± 0%   +8.33% (p=0.002 n=6)      51.00 ± 0%   +6.25% (p=0.002 n=6)
NewFastRegexMatcher/.+-10                                    45.00 ± 0%        48.00 ± 0%   +6.67% (p=0.002 n=6)      49.00 ± 0%   +8.89% (p=0.002 n=6)      48.00 ± 0%   +6.67% (p=0.002 n=6)
NewFastRegexMatcher/foo.+-10                                 75.00 ± 0%        78.00 ± 0%   +4.00% (p=0.002 n=6)      79.00 ± 0%   +5.33% (p=0.002 n=6)      78.00 ± 0%   +4.00% (p=0.002 n=6)
NewFastRegexMatcher/.+foo-10                                 67.00 ± 0%        70.00 ± 0%   +4.48% (p=0.002 n=6)      71.00 ± 0%   +5.97% (p=0.002 n=6)      70.00 ± 0%   +4.48% (p=0.002 n=6)
NewFastRegexMatcher/foo_.+-10                                77.00 ± 0%        80.00 ± 0%   +3.90% (p=0.002 n=6)      81.00 ± 0%   +5.19% (p=0.002 n=6)      80.00 ± 0%   +3.90% (p=0.002 n=6)
NewFastRegexMatcher/foo_.*-10                                76.00 ± 0%        79.00 ± 0%   +3.95% (p=0.002 n=6)      80.00 ± 0%   +5.26% (p=0.002 n=6)      79.00 ± 0%   +3.95% (p=0.002 n=6)
NewFastRegexMatcher/.*foo.*-10                               72.00 ± 0%        75.00 ± 0%   +4.17% (p=0.002 n=6)      76.00 ± 0%   +5.56% (p=0.002 n=6)      75.00 ± 0%   +4.17% (p=0.002 n=6)
NewFastRegexMatcher/.+foo.+-10                               75.00 ± 0%        78.00 ± 0%   +4.00% (p=0.002 n=6)      79.00 ± 0%   +5.33% (p=0.002 n=6)      78.00 ± 0%   +4.00% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.*)-10                               48.00 ± 0%        51.00 ± 0%   +6.25% (p=0.002 n=6)      52.00 ± 0%   +8.33% (p=0.002 n=6)      51.00 ± 0%   +6.25% (p=0.002 n=6)
NewFastRegexMatcher/(?s:.+)-10                               46.00 ± 0%        49.00 ± 0%   +6.52% (p=0.002 n=6)      50.00 ± 0%   +8.70% (p=0.002 n=6)      49.00 ± 0%   +6.52% (p=0.002 n=6)
NewFastRegexMatcher/(?s:^.*foo$)-10                          73.00 ± 0%        76.00 ± 0%   +4.11% (p=0.002 n=6)      77.00 ± 0%   +5.48% (p=0.002 n=6)      76.00 ± 0%   +4.11% (p=0.002 n=6)
NewFastRegexMatcher/(?i:foo)-10                              61.00 ± 0%        64.00 ± 0%   +4.92% (p=0.002 n=6)      65.00 ± 0%   +6.56% (p=0.002 n=6)      64.00 ± 0%   +4.92% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo|bar))-10                        105.0 ± 0%        108.0 ± 0%   +2.86% (p=0.002 n=6)      109.0 ± 0%   +3.81% (p=0.002 n=6)      108.0 ± 0%   +2.86% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|bar))-10                  135.0 ± 0%        138.0 ± 0%   +2.22% (p=0.002 n=6)      139.0 ± 0%   +2.96% (p=0.002 n=6)      138.0 ± 0%   +2.22% (p=0.002 n=6)
NewFastRegexMatcher/^(?i:foo|oo)|(bar)$-10                   133.0 ± 0%        136.0 ± 0%   +2.26% (p=0.002 n=6)      137.0 ± 0%   +3.01% (p=0.002 n=6)      136.0 ± 0%   +2.26% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10      428.0 ± 0%        405.0 ± 0%   -5.37% (p=0.002 n=6)      432.0 ± 0%   +0.93% (p=0.002 n=6)      436.0 ± 0%   +1.87% (p=0.002 n=6)
NewFastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10           147.0 ± 0%        150.0 ± 0%   +2.04% (p=0.002 n=6)      151.0 ± 0%   +2.72% (p=0.002 n=6)      150.0 ± 0%   +2.04% (p=0.002 n=6)
NewFastRegexMatcher/^$-10                                    47.00 ± 0%        50.00 ± 0%   +6.38% (p=0.002 n=6)      51.00 ± 0%   +8.51% (p=0.002 n=6)      50.00 ± 0%   +6.38% (p=0.002 n=6)
NewFastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10       178.0 ± 0%        181.0 ± 0%   +1.69% (p=0.002 n=6)      182.0 ± 0%   +2.25% (p=0.002 n=6)      181.0 ± 0%   +1.69% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2)\.+-10                       94.00 ± 0%        97.00 ± 0%   +3.19% (p=0.002 n=6)      98.00 ± 0%   +4.26% (p=0.002 n=6)      97.00 ± 0%   +3.19% (p=0.002 n=6)
NewFastRegexMatcher/10\.0\.(1|2).+-10                        107.0 ± 0%        110.0 ± 0%   +2.80% (p=0.002 n=6)      111.0 ± 0%   +3.74% (p=0.002 n=6)      110.0 ± 0%   +2.80% (p=0.002 n=6)
NewFastRegexMatcher/((fo(bar))|.+foo)-10                     112.0 ± 0%        115.0 ± 0%   +2.68% (p=0.002 n=6)      116.0 ± 0%   +3.57% (p=0.002 n=6)      115.0 ± 0%   +2.68% (p=0.002 n=6)
NewFastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10    1228.00 ± 0%      1448.00 ± 0%  +17.92% (p=0.002 n=6)      13.00 ± 0%  -98.94% (p=0.002 n=6)      17.00 ± 0%  -98.62% (p=0.002 n=6)
NewFastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10   30727.00 ± 0%     12236.00 ± 0%  -60.18% (p=0.002 n=6)      63.00 ± 0%  -99.79% (p=0.002 n=6)      65.00 ± 2%  -99.79% (p=0.002 n=6)
NewFastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10     1.497k ± 0%       1.400k ± 0%   -6.48% (p=0.002 n=6)     1.501k ± 0%   +0.27% (p=0.002 n=6)     1.510k ± 0%   +0.87% (p=0.002 n=6)
FastRegexMatcher/foo-10                                      0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^foo-10                                     0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(foo|bar)-10                                0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.*-10                                    0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo-10                                    0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.*foo$-10                                  0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^.+foo$-10                                  0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*-10                                       0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+-10                                       0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo.+-10                                    0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo-10                                    0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.+-10                                   0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/foo_.*-10                                   0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.*foo.*-10                                  0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/.+foo.+-10                                  0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.*)-10                                  0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:.+)-10                                  0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?s:^.*foo$)-10                             0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:foo)-10                                 0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo|bar))-10                           0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|bar))-10                     0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^(?i:foo|oo)|(bar)$-10                      0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(foo1|foo2|aaa|bbb|ccc|ddd|e-10         18.00 ± 0%        18.00 ± 0%        ~ (p=1.000 n=6) ¹    18.00 ± 0%        ~ (p=1.000 n=6) ¹    18.00 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/((.*)(bar|b|buzz)(.+)|foo)$-10              0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/^$-10                                       0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(prometheus|api_prom)_api_v1_.+-10          0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2)\.+-10                          0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/10\.0\.(1|2).+-10                           0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/((fo(bar))|.+foo)-10                        0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKM-10         0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/jyyfj00j0061|jyyfj00j0062|jyyfj9-10         0.000 ± 0%        0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹    0.000 ± 0%        ~ (p=1.000 n=6) ¹
FastRegexMatcher/(?i:(zQPbMkNO|NNSPdvMi|iWuuSoAl|-10         18.00 ± 0%        18.00 ± 0%        ~ (p=1.000 n=6) ¹    18.00 ± 0%        ~ (p=1.000 n=6) ¹    18.00 ± 0%        ~ (p=1.000 n=6) ¹
geomean                                                                 ²                   -2.27%               ²                -16.42%               ²                -16.70%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

@Logiraptor Logiraptor changed the title Use a prefix trie for long alternate lists Optimize long alternate lists Mar 30, 2023
model/labels/regexp.go Outdated Show resolved Hide resolved
model/labels/regexp.go Outdated Show resolved Hide resolved
model/labels/regexp.go Outdated Show resolved Hide resolved
@Logiraptor Logiraptor force-pushed the logiraptor/optimize-alternating-literals branch from 828342e to 297c90f Compare March 31, 2023 20:30
@Logiraptor Logiraptor marked this pull request as ready for review March 31, 2023 20:37
@Logiraptor
Copy link
Contributor Author

Logiraptor commented Mar 31, 2023

Now with this PR and #465 together:

I downloaded a dataset of 713287 real queries from the cell where this issue was discovered (Cell A), and 504496 queries from a shared cell where this issue is not noticeable (Cell B). I wrote a small program to parse the queries and throw away the result. Much of this time is spent reading the queries from disk or running GC, but nonetheless the results are promising:

cell timed section before after
Cell A total time 180.70s 16.72s
ParseExpr 24s 2.5s
Cell B total time 9.6s 6.44s
ParseExpr 1.2s 0.5s

@Logiraptor Logiraptor requested a review from pracucci March 31, 2023 21:44
Copy link
Collaborator

@pracucci pracucci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing job, I like it. Let's go! 🚀

@pracucci pracucci merged commit ae170f6 into main Apr 1, 2023
@pracucci pracucci deleted the logiraptor/optimize-alternating-literals branch April 1, 2023 06:35
Logiraptor added a commit that referenced this pull request Jan 2, 2024
I was surprised to find out that posting lookups for `foo=~"(bar|bar)"`
are faster than `foo=~"bar"`. It turns out we introduced a performance
regression in #463.

When we added the `optimizeAlternatingLiterals` function, we subtly
broke one edge case. A regexp matcher which matches a single literal,
like `foo=~"bar"` used to return `bar` from `SetMatches()`, but
currently does not. The implication is that the tsdb will first do a
LabelValues call to get all values for `foo`, then match them against
the regexp `bar`. This PR restores the previous behavior which is able
to directly lookup postings for `foo="bar"` instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants