2017年11月30日木曜日

ちょっとEulerは一休みでフィボナッチ数列のベンチをしてみた。

再帰でフィボナッチ数列を計算する関数を作成しfib(39)の値を求めるまでの所要時間を表示させるもの

C#(Debug)  4.132秒
C#(リリース) 1.071秒
ruby2.3.3         12.188秒
access(2010)    17.500秒

VBAでこれだけ掛かるし汎用の再帰の関数が定義できない昔のBASICは試すまでもない。
と言いつつ「N88-basicによる はじめてのアルゴリズム入門」河西朝雄著 P.163に
ソースがあったので改造してベンチマークしてみた。
結果は
99basic   383秒
まあよく終わったなって感じですね。ご苦労さまでした。
これはもう結構遅いと感じたAccessのVBAの20倍の所要時間とは恐ろしい。
しかし問題はそんなことではない。関数が独立したものとして記述できないので単なる戻り場所を記憶したGOTO文にしか過ぎないgosubを再帰的に呼ぶために呼び出し時の変数をスタックに記憶しなければならない。その上スタックのサイズにも気を使わざるを得ず、元の資料では1000用意していた配列を6000に拡大して動かした。
また整数の範囲も-32768から32767の2byteなため解に到達できないし単なる宣言では単精度の浮動小数の型が適用されるため途中で末尾に誤差が生じ始める始末。
あらかじめそのへんの事情を知っていて手を打って初めて解に到達できるというのは厳しい。

javaとActiveBaic4も試してみた
ab4(Debug)     146.002秒 
ab4(Release)      5.226秒
java8                 0.430秒(何度か試行しての平均)

javaはさすがの結果
手持ちコンパイラの最速はmandelに続いて揺るがず
ただし文字列⇔数値の変換の記述がC#よりも複雑な気がする
技術評論社の「とっさのJava すぐに使える頻出フレーズ300」の必要性がわかった

activebasicのデバッグコンパイルとリリースコンパイルの差が大きいことに驚き。
C#だと4倍程度の差なのに30倍近く差がついた

ab4のソース 綺麗に機能が記述できて最低限のプログラミング要素を満たしてます。
#N88BASIC

' ::: c.f. http://www.activebasic.com/forum/viewtopic.php?t=786
Const cx=640'幅
Const cy=480'高さ
SetWindowPos(_PromptSys_hWnd,HWND_TOP,0,0,cx,cy,SWP_DRAWFRAME or SWP_NOMOVE or SWP_SHOWWINDOW)

dim st as DWORD,ed as DWORD
dim ans as string

function fib(n as long) as long
if n<2 then
fib=n
Else
fib=fib(n-1)+fib(n-2)
end if
end function

st=GetTickCount()
print fib(39)
ed=GetTickCount()

print "  所要時間 : ";ed-st;"ms   "
ans = Input$(1)


0 件のコメント:

dosvaxj3が更新されていた。

 最近、エミュレータ系をあまり触っていなかったのだけど久しぶりに見てみたらタイトルのようにdosvaxj3が更新されていた。 on emulatorでセルフにcなどのソースを書いて実行するのに母艦側の特定のフォルダをドライブとしてマウント出来たり普通に母艦のimeで漢字が入力でき...