Skip to content

Replace vtable dispatch with switch-case in match_all_states and unwind (up to ~2x speedup) - #284

Open
e4d08 wants to merge 1 commit into
boostorg:developfrom
e4d08:performance/no_vtables
Open

Replace vtable dispatch with switch-case in match_all_states and unwind (up to ~2x speedup)#284
e4d08 wants to merge 1 commit into
boostorg:developfrom
e4d08:performance/no_vtables

Conversation

@e4d08

@e4d08 e4d08 commented Jul 27, 2026

Copy link
Copy Markdown

The perl_matcher's match_all_states() and unwind() used static vtables of member function pointers (s_match_vtable[34] and s_unwind_table[19]) to dispatch on the current state type. This replaces them with a direct switch-case dispatch, which enables better branch prediction.

Changes

  • Replaced the static matcher_proc_type s_match_vtable[34] array with a switch(pstate->type) in the main match loop (perl_matcher_non_recursive.hpp (include/boost/regex/v5/perl_matcher_non_recursive.hpp))
  • Replaced the static unwind_proc_type s_unwind_table[19] array with a switch(m_backup_state->state_id) in unwind()
  • Removed the unwind_proc_type typedef from perl_matcher.hpp
  • Replaced magic number literals in saved_state construction (15, 16, 17, 18) with named enum values (saved_state_recursion_pop, saved_state_commit, saved_state_then, saved_state_change_case).

Performance effect

Benchmarked with the tests from ./performance regex_perf.cpp on Intel Core i3-4005U CPU @ 1.70GHz.

Test vtables switch
Literal abc (extended) 3.468 ms 2.888 ms (1.20x)
Email address validation (perl) 12.761 ms 7.858 ms (1.62x)
Simple alternation Beman|John|Dave (perl) 79.611 ms 72.322 ms (1.10x)
HTML <p> tag, case-insensitive (perl) 313.001 ms 207.437 ms (1.51x)
HTML <a> anchor tag (extended) 1,545.587 ms 1,266.425 ms (1.22x)
HTML <a> anchor tag, case-insensitive (perl) 502.679 ms 357.452 ms (1.41x)
HTML <font> tag with contents, case-insensitive (perl) 364.229 ms 217.004 ms (1.68x)
C++ syntax highlighting pattern (perl) 92,775.666 ms 44,371.532 ms (2.09x)
C++ class/struct declaration (perl) 19,326.816 ms 14,857.844 ms (1.30x)
Boost #include directives (perl) 2,259.924 ms 1,922.954 ms (1.18x)

Run with:

g++ -std=c++17 -O3 regex_perf.cpp -o regex_perf
taskset --cpu-list 1 ./regex_perf

…tates and unwind

Remove static arrays of member function pointers (s_match_vtable, s_unwind_table)
and replace them with switch-case dispatch in match_all_states() and unwind().
This eliminates static data that could cause runtime initialization issues on
some compilers, and improves clarity.

Also replace magic number arguments to saved_state constructor with named
enum values from saved_state_type.
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.

1 participant