Date: Thu, 15 Oct 2009 12:28:35 -0400 From: Taylor R Campbell campbell@mumble.net
Date: Thu, 15 Oct 2009 12:22:37 -0400 From: Bradley Lucier lucier@math.purdue.edu
In other words, this mechanical translation of do loops to named lets (following the known continuation when each loop is finished) more than doubles the speed of the routine.
I've trained myself to write loops as named lets, but other people have not yet been assimilated to modify how they write code to get around the oddities of Gambit's compiler. Do loops are very popular in numerical code; please add a transformation like this to the compiler.
I'm puzzled: how is DO implemented in Gambit, if not as a macro that performs precisely that transformation?
I see: Gambit is probably transforming DO the obvious way, to yield
... (let k-loop ((k 0)) (if (fx= k nr2) (matrix-set! r i j a) ...)) (j-loop (fx+ j 1)) ...
But Gambit is not performing the control flow analysis necessary to observe that the continuation of the initial call to K-LOOP -- the continuation which calls J-LOOP -- will be used only once, and can be integrated in-line at its single call site to yield
... (let k-loop ((k 0)) (if (fx= k nr2) (begin (matrix-set! r i j a) (j-loop (fx+ j 1))) ...)) ...
So Gambit is pushing some unnecessary stack frames in this loop.