rubyバイナリの速さをベンチマークで比べてみる

折角いろんなバイナリを作られるようになったので、速さを比較してみる。
アーキテクチャi386 = 32ビット、x86_64 = 64ビット、ppc = 32ビットの3種類。ppc64のバイナリは動作させられないようで、rubyコンパイルもできなかった。
こんな最低限のソースから作ったものですら実行できないので、configureにコケルのです。

MyMac:~ chcoopu$ cat ppc64test.c 
int main(void){
  return 0;
}
MyMac:~ chcoopu$ gcc -arch ppc64 -O0 ppc64test.c -o ppc64test   
MyMac:~ chcoopu$ file ppc64test
ppc64test: Mach-O 64-bit executable ppc64
MyMac:~ chcoopu$ ./ppc64test 
-bash: ./ppc64test: Bad CPU type in executable
MyMac:~ chcoopu$ 


また、使用したコンパイラXcode 3.1に付属していたgcc-4.0とgcc-4.2の2種類。
コンパイルには

CC=gcc-4.0またはgcc-4.2

CFLAGS="-O2 -pipe -arch それぞれのアーキテクチャ"

状態で

./configure --prefix=インストール場所 --enable-shared

してコンパイルしたもの。一部configureファイルやMakefileでLDSHAREDの値を

cc -dynamiclib ...

から

$(CC) -arch それぞれのアーキテクチャ -dynamiclib ...

に変更してコンパイルしている。


そうしてできたバイナリを使って、ベンチマークを動かしている。ベンチマーク自体はRuby作者のMatzさんも取り上げているフラクタルベンチマーク実際のコード

これを以下のようにして連続3回実行している。

date; time /usr/local/ruby/ruby-1.8.6-i386-gcc-4.0/bin/ruby fractal.rb; date; time /usr/local/ruby/ruby-1.8.6-i386-gcc-4.0/bin/ruby fractal.rb; date; time /usr/local/ruby/ruby-1.8.6-i386-gcc-4.0/bin/ruby fractal.rb; date

それぞれのバイナリのインストールしたフォルダ名を別々にしてあるので、そこは変更する。フォルダ名にはアーキテクチャ名やコンパイラ名を入れてあるので、間違うことはないだろう。
以下3回の実行時間の平均。

*アーキテクチャ *コンパイラ 実行時間(s)
i386 gcc-4.0 6.248884
i386 gcc-4.2 6.295775
x86_64 gcc-4.0 5.873572
x86_64 gcc-4.2 6.141422
ppc gcc-4.0 15.694515
ppc gcc-4.2 18.666161

実行すると端末に「*」を使ってフラクタル画像が出力されるのだが、ppcバイナリの場合ははっきりと遅いことが感じられた。ロゼッタによる実行時変換に時間がかかっているんだろう。

また、折角Javaも入っているのでJRubyでも実行してみた。
JRuby環境変数JAVA_HOME以下にあるJava VMを使うので、JAVA_HOMEを切り替えており、確認のための出力もしている。使用したのはJava1.5.0の32ビットClient VM、同64ビットServer VM、Java1.6.0の64ビットServer VMの3種類。JRuby自体は全てで1.1.5を使用。

JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home; export JAVA_HOME; $JAVA_HOME/bin/java -client -version; date; time /usr/local/ruby/jruby-1.1.5/bin/jruby --client fractal.rb; date; time /usr/local/ruby/jruby-1.1.5/bin/jruby --client fractal.rb; date; time /usr/local/ruby/jruby-1.1.5/bin/jruby --client fractal.rb; date

こちらも同様に平均。

*JavaVMバージョン *起動VM 実行時間(s)
Java 1.5.0 32ビット Client VM 4.538105
Java 1.5.0 32ビット Server VM 3.580182
Java 1.5.0 64ビット Server VM 3.960026
Java 1.6.0 64ビット Server VM 3.147230

実行するとCのrubyとは違い、最初にフラクタル画像が出力される前に、突っかかるように一旦止まる。これはJava VMの起動にかかっている時間だろう。なので、ruby内で計測している上記実行時間よりも、実際の実行時間は長い。

総括

  • gcc-4.0で作ったバイナリはgcc-4.2で作ったバイナリよりも速い……気がする。
  • i386で32ビットなバイナリよりx86_64で64ビットなバイナリの方が速い……と思う。
  • JavaはClient VMよりもServer VMの方が速い……と言っていいと思う。
  • Java 1.6.0はJava 1.5.0よりも速い……のだろう。

といった辺りはほぼ言える。
rubyjrubyの比較は一概には言えない。今回のフラクタルベンチマークではjrubyの方が速かったが、単にこれだけかもしれない。
傾向として見えてくるほどに色んなベンチマークを色んな環境で試した訳ではないし、そもそも実アプリではないので参考程度にとどめるべきだし、最終的には自分の使いたいアプリで、どれが速いかを実測するべき。
なぜ今回比較したかというと、おもしろそうだったから。それだけ。

以下、実行時の生の出力のみ。
と思ったのだが、長過ぎるせいか途中できれるのでエントリ分割。

まとめていたら、Java 1.5.0のServer VMは、64ビットではなく32ビットで動作していたので、修正&64ビットの結果も取得。