diff options
author | David Mitchell <davem@iabyn.com> | 2011-07-14 16:35:26 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2011-07-14 17:23:17 +0100 |
commit | db4d68cf2dda3f17d4e9fb440385189f55271b32 (patch) | |
tree | ff5bc18625827c63d279962b641ee74b0eae10dd /op.c | |
parent | 0e1b3a4b35c4f6798b244c5b82edcf759e9e6806 (diff) | |
download | perl-db4d68cf2dda3f17d4e9fb440385189f55271b32.tar.gz |
fully short-circuit &&, ||, //
Currently in an expression like (A || B || C || D), if A is true, then
B, C and D aren't evaluated, but the 2nd, 3rd and 4th OR ops are *still*
executed. Use the peephole optimiser to bypass them.
i.e. change the op tree from
- A - OR - OR - OR - X---
\ / \ / \ /
B C D
to
- A - OR --------------------X---
\ /
B - OR -----------/
\ /
C - OR --/
\ /
D
With this, the following code's execution time reduces from 1.6s to 0.9s
approx on my system:
my $a = 1; my $b = 0; my $x = 0;
for (1..10_000_000) {
if ($a || $b || $b || $b || $b || $b) {
$x++;
}
}
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 3 |
1 files changed, 3 insertions, 0 deletions
@@ -9623,6 +9623,9 @@ Perl_rpeep(pTHX_ register OP *o) sop = fop->op_sibling; while (cLOGOP->op_other->op_type == OP_NULL) cLOGOP->op_other = cLOGOP->op_other->op_next; + while (o->op_next && ( o->op_type == o->op_next->op_type + || o->op_next->op_type == OP_NULL)) + o->op_next = o->op_next->op_next; DEFER(cLOGOP->op_other); stitch_keys: |