階乗の計算[ruby][gdgd]

末尾再帰とかいろいろあるみたい。

def func1 n  #たぶん末尾再帰
  def func_tail(a,b)
    (a==0)? b : func_tail(a-1, a*b)
  end
  func_tail(n,1)
end

def func2 n #injectを使った一番普通な感じの
  (1..n).inject(1) {|result,i| result * i}
end

def func3(n,r=[1]) #これは何に当てはまるんだろ?
  r[n] ||= n*func3(n-1,r)
end

速度を計ってみると

require 'benchmark'
Benchmark.bmbm do |x|
  n=1000
  x.report("tail") { func1 n }
  x.report("inject") { func2 n }
  x.report("array") { func3 n }
end

Rehearsal ------------------------------------------
tail     0.000000   0.010000   0.010000 (  0.017285)
inject   0.020000   0.010000   0.030000 (  0.018131)
array    0.030000   0.000000   0.030000 (  0.029766)
--------------------------------- total: 0.070000sec

             user     system      total        real
tail     0.010000   0.000000   0.010000 (  0.014745)
inject   0.010000   0.000000   0.010000 (  0.007555)
array    0.010000   0.000000   0.010000 (  0.012407)

ふつうにInjectがいちばん速い。