summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-10 15:48:02 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-27 11:30:22 +0100
commit748f2c65599942147442f443949449a965f6d608 (patch)
treee0ccd923e221f95c7ddb80fc5c6c4c42c85c5a8f /t
parent4fa080dbc664ee90dd374a9a49ac0a4932421bd7 (diff)
downloadperl-748f2c65599942147442f443949449a965f6d608.tar.gz
optimise away OP_KEYS op in scalar/void context
In something like if (keys %h) { ... } the 'keys %h' is implemented as the op sequences gv[*h] s rv2hv lKRM/1 keys[t2] sK/1 or padhv[%h:1,6] lRM keys[t2] sK/1 It turns out that (%h) in scalar and void context now behaves very similarly to (keys %h) (except that it reset the iterator), so in these cases, convert the two ops rv2hv/padhv, keys into the single op rv2hv/padhv with a private flag indicating that the op is handling the 'keys' action by itself. As well as one less op to execute, this brings the boolean-context optimisation already present in padhv/rv2sv to keys. So if (keys %h) { ... } is no longer slower than if (%h) { ... }
Diffstat (limited to 't')
-rw-r--r--t/perf/benchmarks10
1 files changed, 10 insertions, 0 deletions
diff --git a/t/perf/benchmarks b/t/perf/benchmarks
index d09f51b401..76d0d74bc9 100644
--- a/t/perf/benchmarks
+++ b/t/perf/benchmarks
@@ -306,6 +306,11 @@
setup => 'my %h;',
code => '!%h',
},
+ 'expr::hash::bool_empty_keys' => {
+ desc => 'empty lexical hash in boolean keys context',
+ setup => 'my %h;',
+ code => '!keys %h',
+ },
'expr::hash::bool_empty_unknown' => {
desc => 'empty lexical hash in unknown context',
setup => 'my ($i, %h); sub f { if (%h) { $i++ }}',
@@ -316,6 +321,11 @@
setup => 'my %h = 1..10;',
code => '!%h',
},
+ 'expr::hash::bool_full_keys' => {
+ desc => 'non-empty lexical hash in keys boolean context',
+ setup => 'my %h = 1..10;',
+ code => '!keys %h',
+ },
(