Repository navigation
Conversation
|
Measured while building git.pi66.xyz. Before patching: After patching: |
kimjooyoon
left a comment
There was a problem hiding this comment.
I checked the lifetime of the new pattern cache with a public Lua-API probe at the exact base/head (two fresh process runs each). The varying-pattern workload retains compiled patterns after every Lua state is closed. Reproducer, raw results and sampled heap profile. This is a bounded retained-heap check; I did not rerun the site benchmarks.
| } | ||
| } | ||
| c := &compiled{insts, pat.MustHead, ncap} | ||
| patCache.Store(p, c) |
There was a problem hiding this comment.
Please give this process-wide cache a finite size or lifetime, with a varying-pattern regression. Each valid pattern is stored before matching, and LState.Close does not release it. In the linked probe, 25,000 distinct nonmatching literal patterns leave about 42 MiB of live Go heap after closing the states and two GCs, versus about 81 KiB at the base. Two fresh process runs agree. Reusing 20,000 existing patterns plateaus; adding 5,000 new ones grows the retained heap again. A long-running host using changing patterns therefore keeps their compiled graphs for the process lifetime, even when it closes its Lua states.
|
@kimjooyoon |
|
it has now become:
|
* build the gsub result once using strings.Builder instead of copying the entire string for each match * cache compiled patterns in pm * reuse MatchData across failed match attempts * remove the unused MatchData return value from recursiveVM * skip the replacement scanner when the replacement contains no `%`
|
@kimjooyoon My previous changes were stupid New results:
|
|
Thanks — this addresses my original process-lifetime retention concern at Two fresh runs of the unchanged public-Lua-API probe leave 83,488 / 83,264 bytes of live Go heap after 25,000 distinct patterns, releasing the states and two GCs. The original head’s archived results were 43,997,392 / 44,012,432 bytes. In an additional single-state probe, this finite serial workload plateaus around 2.07 MB. Source-bound results and additional probe. Local ordinary |


While profiling Merodi, I found that
strGsubDoReplaceaccounted for 87% of total allocations (1154 MB). This PR reduces memory usage and CPU time instring.gsuband pattern matching.Changes
gsubresult once usingstrings.Builder.%.pm.Find.MatchDataacross failed match attempts.MatchDatatorecursiveVMinstead of returning it.Results
Benchmarked using the same build before and after:
strGsubDoReplacememory