diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-11-24 01:09:14 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-11-24 01:45:32 -0800 |
commit | 804b5ed7b6140d5110359c81438a8dea7f5b0e04 (patch) | |
tree | c0fec147f59026fa9ee470d8e6e9e50a3303c436 /sv.c | |
parent | 5668452f0dfcb2591dfb8da07389b99e8823a280 (diff) | |
download | perl-804b5ed7b6140d5110359c81438a8dea7f5b0e04.tar.gz |
Make assignment over glob copies much faster
sv_force_normal is passed the SV_COW_DROP_PV flag if the scalar is
about to be written over. That flag is not currently used. We can
speed up assignment over fake GVs a lot by taking advantage of the flag.
Before and after:
$ time ./perl -e '$x = *foo, undef $x for 1..2000000'
real 0m4.264s
user 0m4.248s
sys 0m0.007s
$ time ./perl -e '$x = *foo, undef $x for 1..2000000'
real 0m1.820s
user 0m1.812s
sys 0m0.005s
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -4806,7 +4806,7 @@ Perl_sv_force_normal_flags(pTHX_ register SV *const sv, const U32 flags) if (SvROK(sv)) sv_unref_flags(sv, flags); else if (SvFAKE(sv) && isGV_with_GP(sv)) - sv_unglob(sv); + sv_unglob(sv, flags); else if (SvFAKE(sv) && SvTYPE(sv) == SVt_REGEXP) { /* Need to downgrade the REGEXP to a simple(r) scalar. This is analogous to sv_unglob. We only need it here, so inline it. */ @@ -9464,7 +9464,7 @@ Perl_sv_bless(pTHX_ SV *const sv, HV *const stash) */ STATIC void -S_sv_unglob(pTHX_ SV *const sv) +S_sv_unglob(pTHX_ SV *const sv, U32 flags) { dVAR; void *xpvmg; @@ -9475,7 +9475,8 @@ S_sv_unglob(pTHX_ SV *const sv) assert(SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); SvFAKE_off(sv); - gv_efullname3(temp, MUTABLE_GV(sv), "*"); + if (!(flags & SV_COW_DROP_PV)) + gv_efullname3(temp, MUTABLE_GV(sv), "*"); if (GvGP(sv)) { if(GvCVu((const GV *)sv) && (stash = GvSTASH(MUTABLE_GV(sv))) @@ -9506,7 +9507,8 @@ S_sv_unglob(pTHX_ SV *const sv) /* Intentionally not calling any local SET magic, as this isn't so much a set operation as merely an internal storage change. */ - sv_setsv_flags(sv, temp, 0); + if (flags & SV_COW_DROP_PV) SvOK_off(sv); + else sv_setsv_flags(sv, temp, 0); } /* |