In perl.git, the branch smoke-me/nicholas/merge-hv-split has been updated <http://perl5.git.perl.org/perl.git/commitdiff/3eefa17713d3fafb6d24fbbf9a159e6d790d1c37?hp=a5c297aab028fd600c251fa2b6fd5f5f4d60201d>
- Log ----------------------------------------------------------------- commit 3eefa17713d3fafb6d24fbbf9a159e6d790d1c37 Author: Nicholas Clark <[email protected]> Date: Fri Feb 22 11:19:17 2013 +0100 In Perl_hv_common(), call S_clear_placeholders() directly. This saves one call to HvPLACEHOLDERS_get(). M hv.c commit 76d5393751777be1331c258c2b63469186d90219 Author: Nicholas Clark <[email protected]> Date: Fri Feb 22 10:52:55 2013 +0100 Clarify why hv_common() tries to clear placeholders before calling hsplit(). Which makes me realise that if we clear placeholders, we may be able to avoid the need to split at all. (In fact, as hv_common() only adds one key to the hash, under the current definition of DO_HSPLIT() which only considers total number of keys, clearing any placeholder is going to be enough to drop the total number of keys, and so no longer trigger the split. But we'll leave the code making a second check, to avoid a tight coupling with the internals of DO_HSPLIT().) M hv.c ----------------------------------------------------------------------- Summary of changes: hv.c | 29 ++++++++++++++++++----------- 1 files changed, 18 insertions(+), 11 deletions(-) diff --git a/hv.c b/hv.c index af722f6..809bd00 100644 --- a/hv.c +++ b/hv.c @@ -797,18 +797,25 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */ if ( DO_HSPLIT(xhv) ) { const STRLEN oldsize = xhv->xhv_max + 1; - - /* This logic was in S_hsplit, but as the shared string table can't - contain placeholders, and we are the only other caller of S_hsplit, - it could only trigger from this callsite. So move it here. */ - if (HvPLACEHOLDERS_get(hv) && !SvREADONLY(hv)) { - /* Can make this clear any placeholders first for non-restricted - hashes, even though Storable rebuilds restricted hashes by + const U32 items = (U32)HvPLACEHOLDERS_get(hv); + + if (items /* hash has placeholders */ + && !SvREADONLY(hv) /* but is not a restricted hash */) { + /* If this hash previously was a "restricted hash" and had + placeholders, but the "restricted" flag has been turned off, + then the placeholders no longer serve any useful purpose. + However, they have the downsides of taking up RAM, and adding + extra steps when finding used values. It's safe to clear them + at this point, even though Storable rebuilds restricted hashes by putting in all the placeholders (first) before turning on the - readonly flag, because Storable always pre-splits the hash. */ - hv_clear_placeholders(hv); - } - hsplit(hv, oldsize, oldsize * 2); + readonly flag, because Storable always pre-splits the hash. + If we're lucky, then we may clear sufficient placeholders to + avoid needing to split the hash at all. */ + clear_placeholders(hv, items); + if (DO_HSPLIT(xhv)) + hsplit(hv, oldsize, oldsize * 2); + } else + hsplit(hv, oldsize, oldsize * 2); } if (return_svp) { -- Perl5 Master Repository
