diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-08-25 13:22:46 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-08-25 14:44:01 -0700 |
commit | 6ea72b3a1069e5b7ba4f03a9fb27f685d3ac4733 (patch) | |
tree | 688252f6052dfe90b2b7d5db98d00e95b8ad9439 /ext | |
parent | a43e79016be2ee77667099f1868307f7788bd811 (diff) | |
download | perl-6ea72b3a1069e5b7ba4f03a9fb27f685d3ac4733.tar.gz |
Optimise %hash in sub { %hash || ... }
In %hash || $foo, the %hash is in scalar context, so it has to iterate
through the buckets to produce statistics on bucket usage.
If the || is in void context, the value returned by hash is only ever
used as a boolean (as || doesn’t have to return it). We already opti-
mise it by adding a boolkeys op when it is known at compile time that
|| will be in void context.
In sub { %hash || $foo } it is not known at compile time that it will
be in void context, so it wasn’t optimised.
This commit optimises it by flagging the %hash at compile time as
being possibly in ‘true boolean’ context. When that flag is set,
the rv2hv and padhv ops call block_gimme() to see whether || is in
void context.
This speeds things up signficantly. Here is what I got after optimis-
ing rv2hv but before doing padhv:
$ time ./miniperl -e '%hash = 1..10000; sub { %hash || 1 }->() for 1..100000'
real 0m0.179s
user 0m0.101s
sys 0m0.005s
$ time ./miniperl -e 'my %hash = 1..10000; sub { %hash || 1 }->() for 1..100000'
real 0m5.446s
user 0m2.419s
sys 0m0.015s
(That example is slightly misleading because of the closure, but the
closure version takes 1 sec. when optimised.)
Diffstat (limited to 'ext')
-rw-r--r-- | ext/B/B/Concise.pm | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm index f0a1b44e20..3f2a93d126 100644 --- a/ext/B/B/Concise.pm +++ b/ext/B/B/Concise.pm @@ -629,6 +629,7 @@ $priv{$_}{16} = "OURINTR" for ("gvsv", "rv2sv", "rv2av", "rv2hv", "r2gv", "enteriter"); $priv{$_}{8} = 'LVSUB' for qw(rv2av rv2gv rv2hv padav padhv aelem helem aslice hslice av2arylen keys rkeys substr pos vec); +$priv{$_}{64} = 'BOOL' for 'rv2hv', 'padhv'; $priv{substr}{16} = 'REPL1ST'; $priv{$_}{16} = "TARGMY" for (map(($_,"s$_"),"chop", "chomp"), |