[MLton] Speedup from unrolling and tail-recursion
Wesley W. Terpstra
terpstra@gkec.tu-darmstadt.de
Fri, 21 Jan 2005 22:51:14 +0100
--lrZ03NoBR/3+SXJZ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
As I understand it, scheme and lisp can do these two optimizations
automatically. I was curious to see how much performance gain MLton
could see from this.
Attached are four versions of a very silly example function.
The human-written version 11428571 ops/ms
Loop unrolled 93023255 ops/ms
Tail recursion optimized 288975581 ops/ms
Tail recursion and loop unrolled 636334712 ops/ms
I understand that automatic tail-recursion is hard to do, but I think a
scheme compiler, Rabbit (?) was able to do it with only a few simple rules.
Recursion/loop unrolling isn't very hard though, and MLton already has
inlining, so why is this not done?
--
Wesley W. Terpstra
--lrZ03NoBR/3+SXJZ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="add.sml"
fun addn 0 = 0
| addn x = addn (x-1) + 1
val n = addn 2000000
val () = print (Int.toString n ^ "\n")
--lrZ03NoBR/3+SXJZ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="addt.sml"
fun addn x =
let
fun tail 0 a = a
| tail x a = tail (x-1) (a+1)
in tail x 0 end
val n = addn 2000000000
val () = print (Int.toString n ^ "\n")
--lrZ03NoBR/3+SXJZ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="addtu.sml"
exception Unreachable
fun addn x =
let
fun tail x a =
if x < 8 then case x of
0 => a
| 1 => a+1
| 2 => a+1+1
| 3 => a+1+1+1
| 4 => a+1+1+1+1
| 5 => a+1+1+1+1+1
| 6 => a+1+1+1+1+1+1
| 7 => a+1+1+1+1+1+1+1
| _ => raise Unreachable
else tail (x-1-1-1-1-1-1-1-1) (a+1+1+1+1+1+1+1+1)
in tail x 0 end
val n = addn 2000000000
val () = print (Int.toString n ^ "\n")
--lrZ03NoBR/3+SXJZ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="addu.sml"
exception Unreachable
fun addn x =
if x < 8 then case x of
0 => 0
| 1 => 1
| 2 => 1+1
| 3 => 1+1+1
| 4 => 1+1+1+1
| 5 => 1+1+1+1+1
| 6 => 1+1+1+1+1+1
| 7 => 1+1+1+1+1+1+1
| _ => raise Unreachable
else addn (x-1-1-1-1-1-1-1-1) +1+1+1+1+1+1+1+1
val n = addn 20000000
val () = print (Int.toString n ^ "\n")
--lrZ03NoBR/3+SXJZ--