diff options
author | Max Maischein <corion@corion.net> | 2009-05-31 23:50:12 +0200 |
---|---|---|
committer | Vincent Pit <perl@profvince.com> | 2009-06-01 21:25:49 +0200 |
commit | 900ac0519e4b408fd93443b14b734cc330c59698 (patch) | |
tree | bd665ce77316d56aa3259e6d16889d75f586cb62 /hv.c | |
parent | 5a1562d6aa780bfc9a14482654d4f7d63a1db386 (diff) | |
download | perl-900ac0519e4b408fd93443b14b734cc330c59698.tar.gz |
Fix RT26188, speed up keys() on empty hash
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 40 |
1 files changed, 23 insertions, 17 deletions
@@ -2143,26 +2143,32 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) } } } - while (!entry) { - /* OK. Come to the end of the current list. Grab the next one. */ - iter->xhv_riter++; /* HvRITER(hv)++ */ - if (iter->xhv_riter > (I32)xhv->xhv_max /* HvRITER(hv) > HvMAX(hv) */) { - /* There is no next one. End of the hash. */ - iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ - break; - } - entry = (HvARRAY(hv))[iter->xhv_riter]; + /* Quick bailout if the hash is empty anyway. + I don't know if placeholders are included in the KEYS count, so a defensive check + */ + if (HvKEYS(hv) || (flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { + while (!entry) { + /* OK. Come to the end of the current list. Grab the next one. */ + + iter->xhv_riter++; /* HvRITER(hv)++ */ + if (iter->xhv_riter > (I32)xhv->xhv_max /* HvRITER(hv) > HvMAX(hv) */) { + /* There is no next one. End of the hash. */ + iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ + break; + } + entry = (HvARRAY(hv))[iter->xhv_riter]; - if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { - /* If we have an entry, but it's a placeholder, don't count it. - Try the next. */ - while (entry && HeVAL(entry) == &PL_sv_placeholder) - entry = HeNEXT(entry); + if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { + /* If we have an entry, but it's a placeholder, don't count it. + Try the next. */ + while (entry && HeVAL(entry) == &PL_sv_placeholder) + entry = HeNEXT(entry); + } + /* Will loop again if this linked list starts NULL + (for HV_ITERNEXT_WANTPLACEHOLDERS) + or if we run through it and find only placeholders. */ } - /* Will loop again if this linked list starts NULL - (for HV_ITERNEXT_WANTPLACEHOLDERS) - or if we run through it and find only placeholders. */ } if (oldentry && HvLAZYDEL(hv)) { /* was deleted earlier? */ |