In perl.git, the branch smoke-me/davem/aassign has been created
<http://perl5.git.perl.org/perl.git/commitdiff/1b9a5415e52c941dcf6a2104fc7923ffa41098a3?hp=0000000000000000000000000000000000000000>
at 1b9a5415e52c941dcf6a2104fc7923ffa41098a3 (commit)
- Log -----------------------------------------------------------------
commit 1b9a5415e52c941dcf6a2104fc7923ffa41098a3
Author: David Mitchell <[email protected]>
Date: Fri Oct 21 14:42:18 2016 +0100
tiearray.t - more fine-grained DESTROY counts
It currently tests once near the end of the script that DESTROY has been
called 3 times. Instead test after each individual scope exit
where we expect DESTROY to be called
M t/op/tiearray.t
commit c6c91af17fcd288bc7413d20b91b10d8f0a659b7
Author: David Mitchell <[email protected]>
Date: Fri Oct 21 14:33:54 2016 +0100
reindent tiearray.t
The indents in this test file were a mixture of 1,2,4, and most
importantly, 0 - which made it very hard to visually see the scope
of lexical vars.
Reindent to a standard 4-char indent.
Also delete trailing whitespace from lines.
Whitespace-only changes
M t/op/tiearray.t
commit f74b019aa3e535907e5a088862089ed18b189dcb
Author: David Mitchell <[email protected]>
Date: Wed Oct 19 09:41:53 2016 +0100
Handle list assignment in list context better
In something like
sub inc { $_++ for @_ }
inc(($a,$b,$c,$d) = (10,20))
The four scalar vars will end up with the values (11,21,1,1), with
the list assign op returning 4 lval scalars to be passed to inc.
However, when the LHS includes a hash or array, any 'empty' scalars weren't
being returned. This:
inc(($a,$b,@array,$c) = (10))
used to leave $b and $c undefined. With this commit, they are both set to
1.
This change broke some tests in hashassign.t, which were added in 2012
by commit v5.17.6-295-gb1babc5. Half these tests were commented as
# this arguable, but this is how it works
and they all tested that a scalar following a hash wasn';t returned in
lvalue context; i.e. they assumes that
inc((%h, $x) = (...))
*wouldn't* increment $x. This commit causes $x to be incremented, and
I've changed the failing tests.
It also adds an EXTEND(SP,1) in the scalar case; otherwise for
scalar(() = @a) with empty @a, it could in theory push the '0' return
value off the end of the stack.
M pp_hot.c
M t/op/aassign.t
M t/op/hashassign.t
commit bbfe8980419009d5a0ea1166d8afef390550e578
Author: David Mitchell <[email protected]>
Date: Wed Oct 5 10:10:56 2016 +0100
Better optimise array and hash assignment
[perl #127999] Slowdown in split + list assign
Re-implement the code that handles e.g.
(..., @a) = (...);
(..., %h) = (...);
to make it a lot faster - more than reversing a performance regression
introduced in 5.24.0 - and fix some bugs. In particular, it now
special-cases an empty RHS, which just clears the aggregate, e.g.
(..., @a) = ()
Getting list assignment correct is quite tricky, due to the possibility of
premature frees, like @a = ($a[0]), and magic/tied values on the LHS or
RHS being triggered too soon/late, which might have side-effects. This
often requires making a copy of each RHS element (and indeed for assigning
to an array or hash, the values need copying anyway). But copying too soon
can result in leaked SVs if magic (such as calling FETCH()) dies. This
usually involves mortalising all the copies, which slows things down.
Further, a bug fix in 5.24.0 added the SV_NOSTEAL flag when copying SVs.
This meant in something like @a = (split(...))[0,0], where the two SvTEMPs
on the RHS are the same, the first copy is no longer allowed to steal the
PVX buffer, which would have made the second SV undef. But this means that
PVX buffers are now always copied, which resulted in the slowdown seen in
RT #127999.
Amongst the general rewriting and optimising, this commit does the
following specific things to boost performance (and fix RT #127999).
* If the SVs on the RHS are non-magical SvTEMPs with a ref count of 1, then
the SV isn't copied; instead it is stored directly in the array/hash. This
more than undoes the cost of SV_NOSTEAL.
* The tmps stack is now used as a temporary refcounted version of the
argument stack frame, meaning that args placed there will be freed on
croak. In something like @a = (....), each RHS element is copied, with
the copy placed on the temps stack. Then @a is cleared. Then the elements
on the tmps stack are stored in the array, and removed from the temps
stack (with the ownership of 1 reference count transferring from the temps
stack to the array). Normally by the time pp_aassign() returns, there is
nothing left on the tmps stack and tmps_free() isn't called - this is the
novel element that distinguishes this from the normal use of mortalising.
* For hash assignment, the keys and values are processed in separate
loops, with keys not normally being copied.
* The ENTER/SAVEFREESV(ary/hash)/LEAVE has been removed, and the array or
hash kept temporarily alive by using the temps stack along with all the
other copied SVs.
* The main 'for each LHS element' loop has been split into two loops: the
second one is run when there no more RHS elements to consume. The second
loop is much simpler, and makes things like @a = () much faster.
Here are the average expr::aassign:: benchmarks for selected perls
(raw numbers - lower is better)
5.6.1 5.22.0 5.24.0 5.25.5 this
------ ------ ------ ------ ------
Ir 1355.9 1497.8 1387.0 1382.0 1146.6
Dr 417.2 454.2 410.1 411.1 335.2
Dw 260.6 270.8 249.0 246.8 194.5
COND 193.5 223.2 212.0 207.7 174.4
IND 25.3 17.6 10.8 10.8 10.0
COND_m 4.1 3.1 3.1 3.7 2.8
IND_m 8.9 6.1 5.5 5.5 5.5
And this code:
my @a;
for my $i (1..10_000_000) {
@a = (1,2,3);
#@a = ();
}
with the empty assign is 33% faster than blead, and without is 12% faster
than blead.
M pp_hot.c
M t/op/aassign.t
M t/op/hash.t
M t/op/tie.t
M t/op/tiearray.t
M t/perf/benchmarks
commit a38007564275732b1c55dec98315a2c18509925e
Author: David Mitchell <[email protected]>
Date: Mon Oct 10 17:10:16 2016 +0100
bench.pl: fix --sort and --compact options
They were using the full pathname of the perl executable to index into
a hash indexed by label.
M Porting/bench.pl
-----------------------------------------------------------------------
--
Perl5 Master Repository