フィボナッチ数列
感想
特に面白いことはなかった
一番素朴な実装が最速な件について
#fib(1000)を計算したとき user system total real fib1 0.010000 0.000000 0.010000 ( 0.010997) fib2 0.010000 0.000000 0.010000 ( 0.001816) fib4 0.010000 0.000000 0.010000 ( 0.010691)
コード
def fib1(n,r=[0,1]) r[n] ||= fib1(n-2,r) + fib1(n-1,r) end def fib2(n) a,b=0,1 n.times{ a,b=b,a+b} a end def fib3 n case n when 0 : 0 when 1 : 1 else fib3(n-2)+fib3(n-1) end end class Fib def initialize @r=[0,1] end def fib4 n @r[n]||=fib4(n-2)+fib4(n-1) end end require 'benchmark' Benchmark.bmbm do |x| n=1000 x.report("fib1"){fib1 n} x.report("fib2"){fib2 n} x.report("fib4"){Fib.new.fib4 n} end
fib1,fib3,fib4はほとんど同じなんだけど・・
それぞれの違い
- fib3 何回も何回も無駄に計算
- fib1 ひとつの計算中では1回だけしかr[n]にあたる式を計算しない。
- fib4 インスタンスが存在する限りは、何度計算してもr[n]を1回だけしか計算しない。
だから、n.times { |i| fib i}のときなどはfib4が早い
でも・・・
include Math def fib5 n ((((1+sqrt(5))/2)**n) - (((1-sqrt(5))/2)**n))/sqrt(5) end user system total real fib5 0.000000 0.010000 0.010000 ( 0.013327)
どう考えても最速はこれです。本当に(ry*1
*1:1000.times { |i| fib i}などだとfib4の方が早くなる。でもメモリ消費量も莫大。