Skip to content

Optimize Aho-Corasick root searches with a skip loop - #11467

Merged
lucioleKi merged 1 commit into
erlang:masterfrom
josevalim:jv-simd-ac
Aug 21, 2026
Merged

Optimize Aho-Corasick root searches with a skip loop#11467
lucioleKi merged 1 commit into
erlang:masterfrom
josevalim:jv-simd-ac

Conversation

@josevalim

@josevalim josevalim commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

We introduce a loop for finding the root of Aho-Corasick state,
which allows it to be better optimized by the compiler.
This shows a 1.67x improvement over the previous algorithm.

Additionally, the root finding loop may be replaced by a SIMD
loop when looking up to 16 bytes on supported platforms.
On supported platforms, the SIMD operation costs 16-bytes
of memory when compiling the pattern.

Benchmarks were run on arm64 macOS. Full-subject searches use a
4 MiB zero-filled subject, 100 searches per sample, and the median
of five samples. Values are searches per second. Counts through 16
use SIMD. The 32-roots measures the scalar skip-loop improvement
independently.

No match:

 roots    before    after    speedup
     1       261     4228     16.20x
     2       262     3414     13.03x
     3       261     2101      8.05x
     4       260     1805      6.94x
     8       258     1147      4.45x
     9       260     1052      4.05x
    16       259      666      2.57x
    32       258      430      1.67x

First match immediately after the 4 MiB prefix:

 roots    before    after    speedup
     1       261     4218     16.16x
     2       261     3354     12.85x
     3       261     2072      7.94x
     4       261     1780      6.82x
     8       260     1141      4.39x
     9       261     1039      3.98x
    16       260      663      2.55x
    32       261      430      1.65x

Pattern compilation uses 100,000 compilations per sample
and the median of seven samples. Values are compilations
per second:

 roots    before    after    change
     2    628559   647903     +3.1%
     3    580009   577474     -0.4%
     4    516172   529459     +2.6%
     8    393026   390299     -0.7%
     9    367666   364475     -0.9%
    16    257562   255865     -0.7%
    32    150395   149792     -0.4%

@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

CT Test Results

    4 files    225 suites   1h 56m 8s ⏱️
3 885 tests 3 756 ✅ 129 💤 0 ❌
4 970 runs  4 818 ✅ 152 💤 0 ❌

Results for commit bb82b27.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

We introduce a loop for finding the root of Aho-Corasick state,
which allows it to be better optimized by the compiler.
This shows a 1.67x improvement over the previous algorithm.

Additionally, the root finding loop may be replaced by a SIMD
loop when looking up to 16 bytes on supported platforms.
On supported platforms, the SIMD operation costs 16-bytes
of memory when compiling the pattern.

Benchmarks were run on arm64 macOS. Full-subject searches use a
4 MiB zero-filled subject, 100 searches per sample, and the median
of five samples. Values are searches per second. Counts through 16
use SIMD. 32 measures the scalar skip-loop improvement independently.

No match:

     roots    before    after    speedup
         1       261     4228     16.20x
         2       262     3414     13.03x
         3       261     2101      8.05x
         4       260     1805      6.94x
         8       258     1147      4.45x
         9       260     1052      4.05x
        16       259      666      2.57x
        32       258      430      1.67x

First match immediately after the 4 MiB prefix:

     roots    before    after    speedup
         1       261     4218     16.16x
         2       261     3354     12.85x
         3       261     2072      7.94x
         4       261     1780      6.82x
         8       260     1141      4.39x
         9       261     1039      3.98x
        16       260      663      2.55x
        32       261      430      1.65x

Pattern compilation uses 100,000 compilations per sample
and the median of seven samples. Values are compilations
per second:

     roots    before    after    change
         2    628559   647903     +3.1%
         3    580009   577474     -0.4%
         4    516172   529459     +2.6%
         8    393026   390299     -0.7%
         9    367666   364475     -0.9%
        16    257562   255865     -0.7%
        32    150395   149792     -0.4%
@jhogberg jhogberg added the team:VM Assigned to OTP team VM label Aug 17, 2026
@lucioleKi lucioleKi added the testing currently being tested, tag is used by OTP internal CI label Aug 17, 2026
@lucioleKi
lucioleKi merged commit a35c061 into erlang:master Aug 21, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team:VM Assigned to OTP team VM testing currently being tested, tag is used by OTP internal CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants