nfa_regmatch() allocates two large thread list buffers (~40KB each) on every call. For :%s on a large file, this means millions of malloc/free calls with the same compiled regexp. This patch caches those buffers in nfa_regprog_T and reuses them on subsequent calls. Recursive calls still allocate their own buffers.
Benchmark: 10K lines, :%s x50 iterations
| Pattern | Before | After | Improvement |
|---|---|---|---|
\<\(\w\+\%(ing|tion|ed|ly\)|\w\{3,}\)\> (many matches) |
4.384s | 4.299s | -2% |
\(foo|bar|baz\)\{3,}\(qux|quux|corge\)\{2,}... (no match, high nstate) |
16.927s | 3.015s | -82% |
The effect is largest when nstate is high and per-line matching work is small, making malloc/free the dominant cost.
https://github.com/vim/vim/pull/19956
(2 files)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()