rakudo/rakudo — pull request #101 by timo (2013-01-27 00:49:07+00:00)
Title: RFC: Partially inline junctions in bool context at compile time

In this branch, I've implemented a runtime optimisation that turns this:

if 1 | 2 | 3 == $x { ... }

into this:

if 1 == (my $temp_var = $x) || 2 == $temp_var || 3 == $temp_var { ... }

in if, unless, while and until statements. On my machine, it makes the whole spectest (which uses almost no junctions) take one second longer than without - it takes 1099 seconds) In this simple benchmark it reduces run time from 5.2 seconds down to 3.2 (down to 60%!):

my $ct = 0;
for (-20..20)X(-20..20) -> $x, $y {
if $x & $y == -1 | 0 | 1 { # only the left junction will be unfolded here.
$ct++
}
}
say $ct;

Looking for more things to put in. One example is, that any(), all() and one() don't work yet, they generate a call to infix:<,>, which I don't handle yet. Also, apparently if the op between the junction and the other side is ~~, it doesn't happen at all - my guess is ~~ isn't "chain".

- [X] Unfold one side of simple junctions with chain ops
- [X] make sure side effects are only evaluated once
- [ ] make ~~ work
- [ ] perhaps fold comparisons between two junctions?
- [ ] make sure chains with multiple comparisons work, too (1 | 2 == $x == $y etc.)