「フィボナッチで各種言語をベンチマーク」をPythonでちょっと掘り下げる。
「フィボナッチで各種言語をベンチマーク」を読んで、予想外にPythonの順位が低かったので。手元の環境はWindows XP SP3/Celeron 1200MHz/512MB RAMのPython 2.7.3、実行2回目以降の時間を以下のコマンドで計測。
rem 「cmd /V:ON」で遅延評価を有効化した状態で以下を実行。
echo !TIME! & C:\Python27\python.exe testx.py & echo !TIME!
まずは掲載されていたスクリプト
def fib(n): if n < 2: return n return fib(n - 2) + fib(n - 1) #print(fib(38)) print fib(38)
Python 2.xの人なのでprintは文にしました、あとインデントはスペース2個に。
計測1回目1分27秒、計測2回目1分26秒。CPUが100%で張り付く感じ。
lambdaで書き直してみる
fib = lambda n : n>=2 and fib(n-2) + fib(n-1) or n print fib(38)
計測1回目1分29秒、計測2回目1分29秒。若干遅くなった。。。
再帰しなければ
def fib(n): #return reduce(lambda x,y: x+[x[-1]+x[-2],], xrange(n-1), [0,1])[-1] # nが0と1の時でもちゃんと動くように変更 return reduce(lambda x,y: x+[x[-1]+x[-2],], xrange(n-1), [0,1])[n] print fib(38)
計測1回目0.2秒、計測2回目0.2秒。信じられんくらい速くなった。。。
結論
やっぱしFAQにある通り関数の呼び出しコストは高し、reduceとかlist演算とか組み込みの機能を使えということでした。