diff options
author | Matthew Horsfall <WolfSage@gmail.com> | 2013-12-11 18:28:21 -0500 |
---|---|---|
committer | Steffen Mueller <smueller@cpan.org> | 2013-12-13 18:15:30 +0100 |
commit | 437e3a7dac994ebace1195549170c81f474d9c20 (patch) | |
tree | 86a8fd6b0a36e0fb66683a245cfdb1d9deb43b78 /ext | |
parent | 4b76cb9db827e0f9f047de33ae98ca8b86be8260 (diff) | |
download | perl-437e3a7dac994ebace1195549170c81f474d9c20.tar.gz |
Optimise out PUSHMARK/RETURN if return is the last statement in a sub.
This makes:
sub baz { return $cat; }
Behave like:
sub baz { $cat; }
Which is notably faster.
Unpatched:
./perl -Ilib/ ~/stuff/bench.pl
Benchmark: timing 40000000 iterations of normal, ret...
normal: 3 wallclock secs ( 1.60 usr + 0.01 sys = 1.61 CPU) @ 24844720.50/s (n=40000000)
ret: 3 wallclock secs ( 2.08 usr + 0.00 sys = 2.08 CPU) @ 19230769.23/s (n=40000000)
Patched:
./perl -Ilib ~/stuff/bench.pl
Benchmark: timing 40000000 iterations of aret, normal...
normal: 2 wallclock secs ( 1.72 usr + 0.00 sys = 1.72 CPU) @ 23255813.95/s (n=40000000)
ret: 2 wallclock secs ( 1.72 usr + 0.00 sys = 1.72 CPU) @ 23255813.95/s (n=40000000)
The difference in OP trees can be seen here:
Unpatched:
$ perl -MO=Concise,baz -e 'sub baz { return $cat }'
main::baz:
5 <1> leavesub[1 ref] K/REFC,1 ->(end)
- <@> lineseq KP ->5
1 <;> nextstate(main 1 -e:1) v ->2
4 <@> return K ->5
2 <0> pushmark s ->3
- <1> ex-rv2sv sK/1 ->4
3 <#> gvsv[*cat] s ->4
-e syntax OK
Patched:
$ ./perl -Ilib -MO=Concise,baz -e 'sub baz { return $cat }'
main::baz:
3 <1> leavesub[1 ref] K/REFC,1 ->(end)
- <@> lineseq KP ->3
1 <;> nextstate(main 1 -e:1) v ->2
- <@> return K ->-
- <0> pushmark s ->2
- <1> ex-rv2sv sK/1 ->-
2 <$> gvsv(*cat) s ->3
-e syntax OK
(Includes some modifications from Steffen)
Diffstat (limited to 'ext')
-rw-r--r-- | ext/B/t/optree_samples.t | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/ext/B/t/optree_samples.t b/ext/B/t/optree_samples.t index 326e0ee617..a4f84c6e9f 100644 --- a/ext/B/t/optree_samples.t +++ b/ext/B/t/optree_samples.t @@ -14,7 +14,7 @@ BEGIN { } use OptreeCheck; use Config; -plan tests => 34; +plan tests => 37; pass("GENERAL OPTREE EXAMPLES"); @@ -637,6 +637,22 @@ EOT_EOT # 6 <@> leave[1 ref] vKP/REFC EONT_EONT +pass("rpeep - return \$x at end of sub"); + +checkOptree ( name => '-exec sub { return 1 }', + code => sub { return 1 }, + bcopts => '-exec', + strip_open_hints => 1, + expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); +# 1 <;> nextstate(main 1 -e:1) v +# 2 <$> const[IV 1] s +# 3 <1> leavesub[1 ref] K/REFC,1 +EOT_EOT +# 1 <;> nextstate(main 1 -e:1) v +# 2 <$> const(IV 1) s +# 3 <1> leavesub[1 ref] K/REFC,1 +EONT_EONT + __END__ ####################################################################### |