more useful options PerlMonks

### Re: Tail recursion using goto &sub; (was: Re^3: Trinary Operator Semantics)

by Roy Johnson (Monsignor)
 on May 27, 2005 at 17:07 UTC ( #461155=note: print w/replies, xml ) Need Help??

Oddly enough, "optimized" tail recursion is significantly slower than recursing the same way without the goto:
```sub faster {
return 0 unless \$_[0];
@_ = (\$_[0] - 1);
&faster;
}
Using this test:
```cmpthese( -10, {
"normal" => sub { normal(50000) },
"tail"   => sub {   tail(50000) },
"faster" => sub { faster(50000) },
}
);
I got these results:
```         Rate normal   tail faster
normal 2.34/s     --    -0%   -41%
tail   2.35/s     0%     --   -41%
faster 3.96/s    69%    68%     --

Caution: Contents may have been coded under pressure.

Replies are listed 'Best First'.
Re^2: Tail recursion using goto ⊂ (was: Re^3: Trinary Operator Semantics)
by demerphq (Chancellor) on May 27, 2005 at 17:59 UTC

Of course a loop is even faster...

```#!perl
use strict;
use Benchmark qw(cmpthese);
my %counter;

sub normal {
return 0 unless \$_[0];
@_ = (\$_[0] - 1);
\$counter{(caller(0))[3]}++;
return normal(@_);
}

sub tail {
return 0 unless \$_[0];
@_ = (\$_[0] - 1);
\$counter{(caller(0))[3]}++;
goto &tail;
}

sub faster {
return 0 unless \$_[0];
@_ = (\$_[0] - 1);
\$counter{(caller(0))[3]}++;
&faster;
}

sub loop {
for (0..\$_[0]) { \$counter{(caller(0))[3]}++; }
return 0;
}

cmpthese( -3, {
"normal" => sub { normal(50000) },
"tail"   => sub {   tail(50000) },
"faster" => sub { faster(50000) },
"loop"   => sub { loop(50000) },
}
);

__END__
Rate normal   tail faster   loop
normal 2.15/s     --    -8%   -18%   -38%
tail   2.35/s     9%     --   -11%   -32%
faster 2.64/s    23%    12%     --   -24%
loop   3.45/s    60%    47%    31%     --

I put the caller thingee in there to ensure that the for loop didnt get optimized away. Which is in itself also a good argument for just using a loop in the first place.

---
\$world=~s/war/peace/g

Re^2: Tail recursion using goto ⊂ (was: Re^3: Trinary Operator Semantics)
by Joost (Canon) on May 27, 2005 at 17:21 UTC
Wierd, though the tail version gets relatively more efficient if you increase the recursion level:
```cmpthese( -10, {
"normal" => sub { normal(500000) },
"tail"   => sub {   tail(500000) },
"faster" => sub { faster(500000) },
}
);
```       s/iter normal   tail faster
normal   2.26     --   -22%   -40%
tail     1.77    28%     --   -23%
faster   1.36    66%    30%     --

Create A New User
Node Status?
node history
Node Type: note [id://461155]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2019-04-20 14:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
I am most likely to install a new module from CPAN if:

Results (110 votes). Check out past polls.

Notices?