RT #127855] Slowdown in m//g on COW strings

Programming / Compilers / PERL - David Mitchell [iabyn.com] - 3 May 2016 10:23 UTC

Better fix for this issue. The previous couple of commits revert an earlier fix for this, which basically modified SvGROW or a particular one of its callers to add 1 to the requested length to ensure that there was space for any future COW reference count (which is stored in spare byte off the end of the string if SvCUR + null byte < SvLEN).

It turns out that sv_grow() already does a +1 over-allocation (added by me with v5.19.0-442-gcbcb2a1), *except* that I made it skip the +1 if the request size seemed to be a large power of two: with the idea being that if someone had requested an exact big power of two then they were probably doing something with buffers, and wouldn't want an 0x10000001 byte buffer when they requested 0x10000000 bytes. This was me basically being conservative. However, I was probably too conservative: the simple test I added just checked that bottom 8 bits were zero and if so, assumed that it was a big buffer request. So as a side effect of this over-simple test, something like 0x13d57f00 wouldn't be incremented to 0x13d57f01.

This is what was discovered in the original report in the the RT ticket: strings allocated with lengths whose lower 8 bits were zero wouldn't have space for a COW refcount, so would become much slower on things like

while $g =~ m/0/g.

This commit improves the test so it only skips the +1 on lengths that are an exact power of 2 and are greater than 0xfff.

9a21f3b RT #127855] Slowdown in m//g on COW strings
sv.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

Upstream: perl5.git.perl.org


  • Share