don't create a copy of keys if it's not LVALUE context
authorRuslan Zakirov <ruz@bestpractical.com>
Wed, 17 Oct 2012 16:04:58 +0000 (20:04 +0400)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 11 Dec 2012 16:59:41 +0000 (08:59 -0800)
Making another copy slows things down. We can avoid it
if aassign is not expected to return LVALUEs.

pp_hot.c

index cd036dd..76a9e43 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -992,9 +992,12 @@ PP(pp_aassign)
     HV *hash;
     I32 i;
     int magic;
     HV *hash;
     I32 i;
     int magic;
+    U32 lval = 0;
 
     PL_delaymagic = DM_DELAY;          /* catch simultaneous items */
     gimme = GIMME_V;
 
     PL_delaymagic = DM_DELAY;          /* catch simultaneous items */
     gimme = GIMME_V;
+    if (gimme == G_ARRAY)
+        lval = PL_op->op_flags & OPf_MOD || LVRET;
 
     /* If there's a common identifier on both sides we have to take
      * special care that assigning the identifier on the left doesn't
 
     /* If there's a common identifier on both sides we have to take
      * special care that assigning the identifier on the left doesn't
@@ -1093,7 +1096,7 @@ PP(pp_aassign)
                while (relem < lastrelem+odd) { /* gobble up all the rest */
                    HE *didstore;
                     assert(*relem);
                while (relem < lastrelem+odd) { /* gobble up all the rest */
                    HE *didstore;
                     assert(*relem);
-                   sv = gimme == G_ARRAY ? sv_mortalcopy(*relem) : *relem;
+                   sv = lval ? sv_mortalcopy(*relem) : *relem;
                    relem++;
                     assert(*relem);
                    tmpstr = sv_mortalcopy( *relem++ ); /* value */
                    relem++;
                     assert(*relem);
                    tmpstr = sv_mortalcopy( *relem++ ); /* value */