diff options
author | David Mitchell <davem@iabyn.com> | 2016-09-19 12:35:13 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2016-10-04 11:18:40 +0100 |
commit | 692044df8403d4568b919fe9ad7e282e864ec85e (patch) | |
tree | cee2e122d90dc7fc942964679cfd808189e5c390 /lib | |
parent | 70027d69be2857dc45d5ff75021fc5f55d6295da (diff) | |
download | perl-692044df8403d4568b919fe9ad7e282e864ec85e.tar.gz |
Better optimise my/local @a = split()
There are currently two optimisations for when the results of a split
are assigned to an array.
For the first,
@array = split(...);
the aassign and padav/rv2av are optimised away, and pp_split() directly
assigns to the array attached to the split op (via op_pmtargetoff or
op_pmtargetgv).
For the second,
my @array = split(...);
local @array = split(...);
@{$expr} = split(...);
The aassign is optimised away, but the padav/rv2av is kept as an additional
arg to split. pp_split itself then uses the first arg popped off the stack
as the array (This was introduced by FC with v5.21.4-409-gef7999f).
This commit moves these two:
my @array = split(...);
local @array = split(...);
from the second case to the first case, by simply setting OPpLVAL_INTRO
on the OP_SPLIT, and making pp_split() do SAVECLEARSV() or save_ary()
as appropriate.
This makes my @a = split(...) a few percent faster.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/B/Deparse.pm | 3 | ||||
-rw-r--r-- | lib/B/Op_private.pm | 8 |
2 files changed, 7 insertions, 4 deletions
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index fb4a7d9fee..e14620ba6a 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -5760,6 +5760,9 @@ sub pp_split { $self->gv_name($gv), $cx)) } + if ($op->private & OPpLVAL_INTRO) { + $ary = $op->private & OPpSPLIT_LEX ? "my $ary" : "local $ary"; + } } } diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm index 1732b04f63..f3693707f5 100644 --- a/lib/B/Op_private.pm +++ b/lib/B/Op_private.pm @@ -133,7 +133,7 @@ $bits{$_}{5} = 'OPpHUSH_VMSISH' for qw(dbstate nextstate); $bits{$_}{1} = 'OPpITER_REVERSED' for qw(enteriter iter); $bits{$_}{7} = 'OPpLVALUE' for qw(leave leaveloop); $bits{$_}{6} = 'OPpLVAL_DEFER' for qw(aelem helem multideref); -$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multideref padav padhv padrange padsv pushmark refassign rv2av rv2gv rv2hv rv2sv); +$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multideref padav padhv padrange padsv pushmark refassign rv2av rv2gv rv2hv rv2sv split); $bits{$_}{2} = 'OPpLVREF_ELEM' for qw(lvref refassign); $bits{$_}{3} = 'OPpLVREF_ITER' for qw(lvref refassign); $bits{$_}{3} = 'OPpMAYBE_LVSUB' for qw(aassign aelem akeys aslice av2arylen avhvswitch helem hslice keys kvaslice kvhslice multideref padav padhv pos rv2av rv2gv rv2hv substr vec); @@ -538,7 +538,7 @@ $bits{snetent}{0} = $bf[0]; @{$bits{sockpair}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); @{$bits{sort}}{6,5,4,3,2,1,0} = ('OPpSORT_STABLE', 'OPpSORT_QSORT', 'OPpSORT_DESCEND', 'OPpSORT_INPLACE', 'OPpSORT_REVERSE', 'OPpSORT_INTEGER', 'OPpSORT_NUMERIC'); @{$bits{splice}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); -@{$bits{split}}{7,4,3} = ('OPpSPLIT_IMPLIM', 'OPpSPLIT_ASSIGN', 'OPpSPLIT_LEX'); +@{$bits{split}}{4,3,2} = ('OPpSPLIT_ASSIGN', 'OPpSPLIT_LEX', 'OPpSPLIT_IMPLIM'); @{$bits{sprintf}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); $bits{sprotoent}{0} = $bf[0]; $bits{sqrt}{0} = $bf[0]; @@ -672,7 +672,7 @@ our %defines = ( OPpSORT_REVERSE => 4, OPpSORT_STABLE => 64, OPpSPLIT_ASSIGN => 16, - OPpSPLIT_IMPLIM => 128, + OPpSPLIT_IMPLIM => 4, OPpSPLIT_LEX => 8, OPpSUBSTR_REPL_FIRST => 16, OPpTARGET_MY => 16, @@ -804,7 +804,7 @@ our %ops_using = ( OPpLIST_GUESSED => [qw(list)], OPpLVALUE => [qw(leave leaveloop)], OPpLVAL_DEFER => [qw(aelem helem multideref)], - OPpLVAL_INTRO => [qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multideref padav padhv padrange padsv pushmark refassign rv2av rv2gv rv2hv rv2sv)], + OPpLVAL_INTRO => [qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multideref padav padhv padrange padsv pushmark refassign rv2av rv2gv rv2hv rv2sv split)], OPpLVREF_ELEM => [qw(lvref refassign)], OPpMAYBE_LVSUB => [qw(aassign aelem akeys aslice av2arylen avhvswitch helem hslice keys kvaslice kvhslice multideref padav padhv pos rv2av rv2gv rv2hv substr vec)], OPpMAYBE_TRUEBOOL => [qw(padhv rv2hv)], |