I have two implementations of the gcd function:
def gcd1(a,b) if a==b a elsif a>b if (a%b)==0 b else gcd1(a%b,b) end else if (b%a)==0 a else gcd1(a,b%a) end end end def gcd2(a,b) if(a==b) return a elsif b>a min,max=a,b else min,max=b,a end while (max%min)!=0 min,max=max%min,min end min end
The gcd1 function is tail recursive, and gcd2 uses a while loop.
I checked that rubinius does TCO by comparing the factorial function, only with the factorial function the tests showed that the recursive version and the iteration version are “the same” (I used benchmark-ips).
But for the above, tests show that gcd1 is at least twice as fast as gcd2 (recursion is twice as fast as iteration, even faster).
The code I used for comparison:
Benchmark.ips do |x| x.report "gcd1 tail recursive" do gcd1(12016,18016) end x.report "gcd2 while loop" do gcd2(12016,18016) end x.compare! end
result:
Warming up -------------------------------------- gcd1 tail recursive 47.720ki/100ms gcd2 while loop 23.118ki/100ms Calculating ------------------------------------- gcd1 tail recursive 874.210k (± 7.1%) i/s - 4.343M gcd2 while loop 299.676k (± 6.6%) i/s - 1.503M Comparison: gcd1 tail recursive: 874209.8 i/s gcd2 while loop: 299676.2 i/s - 2.92x slower
I am running Arch linux x64, processor i5-5200 2.2 GHZ quad-core.
Ruby implementation - Rubinius 3.40.
So how can recursion be faster than a loop?
Update
Just to say that the fibonacci has the same situation: the tail recursive version is at least twice as fast as the loop version, the program I used for fibonacci: http://pastebin.com/C8ZFB0FR