Dart vs. JavaScript vs. Haskell vs. C++ // n-body benchmarking!!
Dart と JavaScript と Haskell と C++ で n-body (多体問題)のベンチマークしたよー。時間測定は全て time ちゃんです。
<※コメントにて runhaskell とコンパイル済みの .o 存在下の挙動について教えて頂き、 runhaskell について測りなおしました!>
結果と感想文
result graph
※Dartのcheckedモードは実際にはグラフの右端から大幅にハミ出しています。
※ runhaskell は2時間ほど経っても完了しませんでした;w;
result table
測ったデータを記録している生のスプレッドシートはこちら。
以下は簡易版。
Language - Implement | compile [sec] | run [sec] | compile+run [sec] |
Haskell - GHC 7.4.1 / runhaskell | 0 | n/a(>12868) | n/a(>12868) |
Haskell - GHC 7.4.1 / ghc | 1.35 | 21.31 | 22.66 |
C++ - GCC 4.6.3 / g++ -O3 | 0.22 | 9.87 | 10.09 |
C++ - GCC 4.6.3 / g++ -O0 | 0.12 | 33.42 | 33.54 |
JavaScript - V8 3.6.6.20 / d8 --nodebugger | 0 | 57.82 | 57.82 |
Dart SDK(2011-03-17/continuous) / dart production |
0 | 172.75 | 172.75 |
Dart SDK(2011-03-17/continuous) / dart checked |
0 | 1906.31 | 1906.31 |
Dart SDK(2011-03-17/continuous) / frogc + JavaScript V8 3.6.6.20 / d8 | 0.85 | 84.33 | 85.18 |
感想文
- うーん…、 Dart VM は思っていたよりは割と遅かった。
runhaskell が輝いて見える。nbody の様な処理を runhaskell に投げちゃうといつまで経っても終わってくれない;w;- C++ かわいいよ C++
簡易版のグラフでは振りきれてしまっていますが、 dart --enable-type-checks は production モードに比べて11倍()も実行時間が必要でした。やはり checked モードは開発者向けのテスト、デバッグ専用としか考えられて居ないみたいですね。
production モードでも JavaScript の3倍もの実行時間を必要とするのは残念でした。この辺りはバックエンドにJava置いてるだけやん…という辺りから含めて、将来的に生でV8より高速にDart仮想マシンが実行される様になると嬉しいな。…遠そうだけど・w・;
ソース
言語ごと
生っぽいログ
Haskell - GHC 7.4.1 - runhaskell & ghc
% time ghc --make -O2 -XBangPatterns -threaded -rtsopts -optc-O3 nbody.hs -o nbody.hs.ghc-7.4.1-O2-XBangPatterns-threaded-rtsopts-optc-O3 (中略) ghc --make -O2 -XBangPatterns -threaded -rtsopts -optc-O3 nbody.hs -o 1.35s user 0.11s system 88% cpu 1.653 total
^Crunhaskell -XBangPatterns nbody.hs 50000000 12868.61s user 38.10s system 100% cpu 3:34:52.09 total
※ runhaskell は現実的な測定時間内での完了は無理でした;w;
./nbody.hs.ghc-7.4.1-O2-XBangPatterns-threaded-rtsopts-optc-O3 +RTS -N1 -RTS 21.76s user 0.04s system 99% cpu 21.910 total ./nbody.hs.ghc-7.4.1-O2-XBangPatterns-threaded-rtsopts-optc-O3 +RTS -N2 -RTS 25.11s user 0.95s system 98% cpu 26.380 total ./nbody.hs.ghc-7.4.1-O2-XBangPatterns-threaded-rtsopts-optc-O3 +RTS -N3 -RTS 35.13s user 4.00s system 113% cpu 34.450 total ./nbody.hs.ghc-7.4.1-O2-XBangPatterns-threaded-rtsopts-optc-O3 +RTS -N4 -RTS 54.76s user 4.03s system 144% cpu 40.786 total ./nbody.hs.ghc-7.4.1-O2-XBangPatterns-threaded-rtsopts-optc-O3 +RTS -N8 -RTS 385.24s user 27.02s system 273% cpu 2:30.65 total
C++ - GCC 4.6.3 - g++
% time g++ -pipe -O3 -fomit-frame-pointer -march=native -lm -mfpmath=sse -msse2 --std=c++0x -mfpmath=sse -msse3 nbody.cpp -o nbody.cpp.g++-4.6.3-pipe-O3-fomit-frame-pointer-march=native-lm-mfpmath=sse-msse2--std=c++0x-mfpmath=sse-msse3 g++ -pipe -O3 -fomit-frame-pointer -march=native -lm -mfpmath=sse -msse2 0.22s user 0.03s system 72% cpu 0.338 total
% time ./nbody.cpp.g++-4.6.3-pipe-O3-fomit-frame-pointer-march=native-lm-mfpmath=sse-msse2--std=c++0x-mfpmath=sse-msse3 50000000 -0.169075164 -0.169059907 50000000 9.87s user 0.00s system 98% cpu 10.010 total
% time g++ -pipe -O2 -fomit-frame-pointer -march=native -lm -mfpmath=sse -msse2 --std=c++0x -mfpmath=sse -msse3 nbody.cpp -o nbody.cpp.g++-4.6.3-pipe-O2-fomit-frame-pointer-march=native-lm-mfpmath=sse-msse2--std=c++0x-mfpmath=sse-msse3 g++ -pipe -O2 -fomit-frame-pointer -march=native -lm -mfpmath=sse -msse2 0.22s user 0.02s system 87% cpu 0.267 total
% time ./nbody.cpp.g++-4.6.3-pipe-O2-fomit-frame-pointer-march=native-lm-mfpmath=sse-msse2--std=c++0x-mfpmath=sse-msse3 50000000 -0.169075164 -0.169059907 50000000 9.87s user 0.00s system 99% cpu 9.875 total
% time g++ -std=c++0x nbody.cpp -o nbody.cpp.g++-4.6.3-std=c++0x g++ -std=c++0x nbody.cpp -o nbody.cpp.g++-4.6.3-std=c++0x 0.12s user 0.03s system 79% cpu 0.196 total
% time ./nbody.cpp.g++-4.6.3-std=c++0x 50000000 -0.169075164 -0.169059907 ./nbody.cpp.g++-4.6.3-std=c++0x 50000000 33.42s user 0.00s system 99% cpu 33.543 total
JavaScript - V8 - d8
d8 --nodebugger nbody.js -- 50000000 57.82s user 0.13s system 100% cpu 57.839 total
Dart - Dart SDK - dart
dart nbody.dart 50000000 172.75s user 0.02s system 99% cpu 2:52.97 total dart --enable-type-checks nbody.dart 50000000 1906.31s user 0.75s system 99% cpu 31:47.39 total
Dart/JavaScript - Dart SDK/V8 - frogc/d8
frogc nbody.dart 0.85s user 0.03s system 92% cpu 0.949 total
※frogcで生成した.dar.jsはコマンドラインからのパラメーターを回収できなくなっていたので、ソース中に埋め込まれたデフォルトの定数値10000を直接50000000に書き換えてから以下は実行した。
d8 --nodebugger nbody.dart.js 84.33s user 0.19s system 100% cpu 1:24.01 total
ベンチマークテストを行った環境
OS: Arch Linux (x86_64) Kernel 3.2.9
CPU: AMD Phenom(tm) II X4 940
MEM: 8GB DDR2-800
DISK: tmpfs 4.0 [GB]
% uname -a Linux LH-MAIN 3.2.9-1-ARCH #1 SMP PREEMPT Thu Mar 1 09:31:13 CET 2012 x86_64 AMD Phenom(tm) II X4 940 Processor AuthenticAMD GNU/Linux
% ghc -V The Glorious Glasgow Haskell Compilation System, version 7.4.1
% runhaskell --version runghc 7.4.1
% g++ --version g++ (GCC) 4.6.3
% d8 V8 version 3.6.6.20 [console: dumb]
dart は 2011-03-17 に入手可能だった継続ビルド版のDart SDKに含まれるものを使用。
(dartには--version的な実装がまだ無い)