From db4d68cf2dda3f17d4e9fb440385189f55271b32 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Thu, 14 Jul 2011 16:35:26 +0100 Subject: [PATCH] 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++; } } --- op.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/op.c b/op.c index 1ad2074..7b129ac 100644 --- a/op.c +++ b/op.c @@ -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: -- 2.7.4