summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-08-21 15:04:09 +0000
committerNicholas Clark <nick@ccl4.org>2021-08-23 08:29:09 +0000
commit77745d701ca519f67def45b50e91f34685ee92e3 (patch)
treebc268cd1dbedecb4d804ebdc06168701d31f19e7 /pp.c
parentfc0034ab201eceb6cc28b88455af900b2ee6b099 (diff)
downloadperl-77745d701ca519f67def45b50e91f34685ee92e3.tar.gz
Pre-extend new anonymous hashes before assigning to them.
We know how many pairs of keys/values are on the stack, so pre-extend the hash to the appropriate size, instead of letting the hash needlessly re-size one or more times during the assignment loop.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/pp.c b/pp.c
index f70d832cf2..10ba861529 100644
--- a/pp.c
+++ b/pp.c
@@ -5525,6 +5525,12 @@ PP(pp_anonhash)
SV* const retval = sv_2mortal( PL_op->op_flags & OPf_SPECIAL
? newRV_noinc(MUTABLE_SV(hv))
: MUTABLE_SV(hv) );
+ /* This isn't quite true for an odd sized list (it's one too few) but it's
+ not worth the runtime +1 just to optimise for the warning case. */
+ SSize_t pairs = (SP - MARK) >> 1;
+ if (pairs > PERL_HASH_DEFAULT_HvMAX) {
+ hv_ksplit(hv, pairs);
+ }
while (MARK < SP) {
SV * const key =