読者です 読者をやめる 読者になる 読者になる

雨谷の日和

過去11年で1,500を超えるアニメの第1話だけは見続けた僕のお勧めアニメがハズレなはずがない

JavaとCとの性能比較(行列式計算/ループ)

ボヤキ - 技術

ということで、ここまでの結果を表にまとめておく。


Pentium4:2.4GHz
WindowsXP(MS932)
cygwin
gcc3.3.1
JDK1.4
Java
最適化
最適化
インタ
プリタ
Hot
Spot
AOT
mallocallocamallocalloca最適化
最適化
配列
最適化
行列式
計算
再帰
有り
動的メモリ確保 468434909555249
事前メモリ確保 55338181065
再帰
無し
動的メモリ確保 443423767525249
事前メモリ確保 3422666754
ループ動的メモリ確保 46-44-15412645252
事前メモリ確保 7744159111986
※単位はいずれも[sec]


一応、実行性能の良い順に書くと結果としては以下のようになっている。


再帰呼び出しを別途の関数に展開」>「再帰呼び出しでの実装」>「再帰呼び出しをループに展開」


別途の関数に展開すると速くなるのが何故なのかは良く分からないが、Javaの実行profileを見る限りでは、何らかの最適化(inline展開など)が行われているためではないかとも思える。
また今回の結果を見る限りでは、単純にループに展開しただけだと速度の向上は無く、むしろ遅くなるという傾向は確かなようだ。
ただ今回の場合、再帰の呼び出し深度は10程度と比較的浅いため、再帰呼び出し自体に性能劣化の要因があるのかどうかは結論できないかも知れない。
ただし再帰の有無は、ソースコードの実行効率を予測する上での判断基準の一つに為り得るという考え方も間違いではない(再帰呼び出しがある場合、無駄なコーディングになっている可能性を検討する方が良い)。
例えば使われている再帰呼び出しが末尾再帰の場合、そのコーディングは本来再帰にする必要のないアルゴリズムであるので、再帰の記述をループに改めるべきであるとは言えるだろう。(ただし、最近のコンパイラは大抵、末尾再帰をループ展開する程度のことはやってくれるらしいので、コーディング段階ではあまり気にする必要もないという意見もある)
今回の場合は末尾再帰ではないので、話はそれ程単純では無かったというだけのことかも知れない。