summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-11-24 01:09:14 -0800
committerFather Chrysostomos <sprout@cpan.org>2011-11-24 01:45:32 -0800
commit804b5ed7b6140d5110359c81438a8dea7f5b0e04 (patch)
treec0fec147f59026fa9ee470d8e6e9e50a3303c436 /sv.c
parent5668452f0dfcb2591dfb8da07389b99e8823a280 (diff)
downloadperl-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.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/sv.c b/sv.c
index 31bda3b2d3..44a8ba6522 100644
--- a/sv.c
+++ b/sv.c
@@ -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);
}
/*