petar-dambovaliev / aho-corasick

efficient string matching in Golang via the aho-corasick algorithm.
MIT License
68 stars 11 forks source link

Do not allocate in NextCandidate. #10

Closed pgavlin closed 1 year ago

pgavlin commented 1 year ago

In practice, the return value of NextCandidate is always either an integer or nil. Change the return type from (interface{}, candidateType) to (int) to avoid allocations on this path.

These changes eliminate the vast majority of the allocations during matching and remove the need for type assertions in callers of NextCandidate. This results in about a 20% speedup across all benchmarks.

aho-corasick ❯ benchstat base.txt nextcand.txt
goos: darwin
goarch: arm64
pkg: github.com/petar-dambovaliev/aho-corasick
                                            │   base.txt   │            nextcand.txt             │
                                            │    sec/op    │   sec/op     vs base                │
Stdlib_StringsReplaceAll/No_matches-10         133.8µ ± 0%   134.4µ ± 1%   +0.38% (p=0.023 n=10)
Stdlib_StringsReplaceAll/Matches-10            118.4µ ± 0%   118.1µ ± 1%        ~ (p=0.424 n=10)
Stdlib_AhoCorasickReplaceAll/No_matches-10     90.91µ ± 0%   73.92µ ± 0%  -18.69% (p=0.000 n=10)
Stdlib_AhoCorasickReplaceAll/Matches-10       101.28µ ± 0%   82.81µ ± 0%  -18.24% (p=0.000 n=10)
AhoCorasick_ReplaceAllDFA-10                   92.13µ ± 0%   74.70µ ± 0%  -18.92% (p=0.000 n=10)
AhoCorasick_ReplaceAllNFA-10                  103.53µ ± 0%   86.04µ ± 0%  -16.89% (p=0.000 n=10)
AhoCorasick_LeftmostInsensitiveWholeWord-10    92.83µ ± 0%   75.62µ ± 0%  -18.54% (p=0.000 n=10)
geomean                                        103.7µ        89.83µ       -13.39%

                                            │   base.txt   │              nextcand.txt              │
                                            │     B/op     │     B/op      vs base                  │
Stdlib_StringsReplaceAll/No_matches-10        112.0Ki ± 0%   112.0Ki ± 0%        ~ (p=1.000 n=10) ¹
Stdlib_StringsReplaceAll/Matches-10           112.0Ki ± 0%   112.0Ki ± 0%        ~ (p=1.000 n=10) ¹
Stdlib_AhoCorasickReplaceAll/No_matches-10    68.95Ki ± 0%   56.11Ki ± 0%  -18.63% (p=0.000 n=10)
Stdlib_AhoCorasickReplaceAll/Matches-10       193.1Ki ± 0%   180.2Ki ± 0%   -6.66% (p=0.000 n=10)
AhoCorasick_ReplaceAllDFA-10                  194.4Ki ± 0%   181.6Ki ± 0%   -6.59% (p=0.000 n=10)
AhoCorasick_ReplaceAllNFA-10                  194.3Ki ± 0%   181.5Ki ± 0%   -6.60% (p=0.000 n=10)
AhoCorasick_LeftmostInsensitiveWholeWord-10   69.69Ki ± 0%   56.88Ki ± 0%  -18.39% (p=0.000 n=10)
geomean                                       123.6Ki        113.2Ki        -8.41%
¹ all samples are equal

                                            │   base.txt    │             nextcand.txt             │
                                            │   allocs/op   │ allocs/op   vs base                  │
Stdlib_StringsReplaceAll/No_matches-10           3.000 ± 0%   3.000 ± 0%        ~ (p=1.000 n=10) ¹
Stdlib_StringsReplaceAll/Matches-10              3.000 ± 0%   3.000 ± 0%        ~ (p=1.000 n=10) ¹
Stdlib_AhoCorasickReplaceAll/No_matches-10    1647.000 ± 0%   3.000 ± 0%  -99.82% (p=0.000 n=10)
Stdlib_AhoCorasickReplaceAll/Matches-10        1667.00 ± 0%   23.00 ± 0%  -98.62% (p=0.000 n=10)
AhoCorasick_ReplaceAllDFA-10                   1721.00 ± 0%   81.00 ± 0%  -95.29% (p=0.000 n=10)
AhoCorasick_ReplaceAllNFA-10                   1704.00 ± 0%   64.00 ± 0%  -96.24% (p=0.000 n=10)
AhoCorasick_LeftmostInsensitiveWholeWord-10    1661.00 ± 0%   21.00 ± 0%  -98.74% (p=0.000 n=10)
geomean                                          275.5        13.14       -95.23%
pgavlin commented 1 year ago

Reopening this from a different branch.

pgavlin commented 1 year ago

https://github.com/petar-dambovaliev/aho-corasick/pull/11