DNA Cafe | Download | FreeSoftware | Java | Links

DNA - Cafe - Java と C++ でメモリ確保が速いのはどちらか

ある日、友人 O からこんなメールがきた。

ね〜、これ ↓ ってホントなのかな?

http://www.ibm.com/jp/developerworks/java/051104/j_j-jtp09275.shtml

手元の環境で new Byte[1024] と new char(1024) を比べてみたのだけど、ヒープが穴だらけにならない限り、C++ の方が数倍速いのですが...

# ヒープを穴だらけにするパターンはまだ試してないので不明。

パフォーマンスは、実際に使う環境と同じ条件で計測しないと意味がない。 だからこの手の計測をしたことはあまりない。

でもね、ふつう Java と C++ の両方で本物のアプリケーションを作って動かすなんて、できない。

そこで、友人が計測した速さと実際のアプリケーションとの差がどこからくるのか、 ちょっと調べてみようと考えた。 どんな振る舞いをするのかがわかればどちらを使うか決めるのに役にたつし、ね。

と、ゆーわけで、実際にベンチマークを作って計測してみることにした。


ベンチマークプログラム

サイズ len のメモリを確保するオブジェクトを単純に N 回作るテストプログラムを C, C++, Java のそれぞれについて作成した。

ベンチマークのソースファイル一式 → malloc_test.tar.bz2 (2643 bytes)

使用した言語
C GCC 3.4.4 gcc -g -O0
C++ GCC 3.4.4 g++ -g -O0
GCJ GCC 3.4.4 gcj -g -O0
Java Sun JDK 1.5.0_05 デフォルトで動作

ハードウエアやソフトウエアの環境

ハードウエアは ThinkPad i1620 2661-23J (M-Celeron 500MHz LV, 320MB) で OS は Linux 2.6.14 + GNU libc 2.3.6 (NPTL を使用)である。 計測には GNU time 1.7 を使い、 コマンド実行のユーザー時間とシステム時間を計測した。 なお、計測値の誤差は測定していないが、複数回試行して傾向が再現することを確認している。

計測結果

結果を図にしたものを以下に示す。縦軸は実行時間(秒)、横軸は確保メモリ数(バイト)である。

1-256k * 100000 times, user time
Fig. 1: 1-256k * 100000 times, user time

1-256k * 100000 times, sys time
Fig. 2: 1-256k * 100000 times, sys time

8k-1M * 10000 times, user time
Fig. 3: 8k-1M * 10000 times, user time

8k-1M * 10000 times, sys time
Fig. 4: 8k-1M * 10000 times, sys time

256k-64M * 1000 times, user time
Fig. 5: 256k-64M * 1000 times, user time

256k-64M * 1000, sys time
Fig. 6: 256k-64M * 1000 times, sys time

考察

このベンチマーク的結論

ハードウエアや OS で結果が変わるだろう、ということをふまえた上で、

  1. 確保メモリが小さいときは C++ が有利
  2. 確保メモリが大きいときは C++ も Java も変わらない
  3. C は確保メモリが大きいときに特に有利(なんか仕掛けがある?)

実際のアプリケーションではどうなるか

多くのアプリケーションでは、小さなオブジェクトが大きなものより多く作られる。 単純に考えると C++ が有利となるはずだが、 Java だと動的にメモリ最適化(例えばメモリコンパクション)ができる利点があり、 これが有効に働く可能性がある。

ベンチマークの結果から見ると Java や GCJGC はかなり優秀で、確保メモリが大きい場合には実時間で C++ と変わらない。 これは、小さなオブジェクトが多い場合でもメモリ最適化が有効に働くと、 実時間で同等になることを意味する。

メモリ管理は OS やライブラリに に組み込まれている機能が多くあり、単純には比較できないが、 Java アプリケーションの性質が GC を有効に利用できるものか、ということが性能に大きくかかわるだろう。

補足

もう少し詳しいベンチマークの結果が shuJIT で知られる首藤さんのページにある。 これを見るとほんとに C++ と Java ってたいして差がないって感じる。


参考ページ

http://slashdot.jp/~oku/journal/327177
パフォーマンスに関する都市伝説の再検証の再検証(元ネタ)
http://www.ibm.com/jp/developerworks/java/051104/j_j-jtp09275.shtml
IBM dW:Javaの理論と実践:パフォーマンスに関する都市伝説を再検証
http://www.shudo.net/jit/perf/
Performance Comparison of Java/.NET Runtimes (英語)

Vector Valid XHTML 1.1! Valid CSS!