Java V.S. C++
昨日の実験結果がちょっと納得いかなかったので,
Java VM V.S. ネイティブコード - なぜか数学者にはワイン好きが多い
単純にループ回数を10倍にしてみました.
> gcj42 -C Pendulum.java S-Euler.java ; jar42 cvfm Pendulum.jar META-INF/MANIFEST.MF *.class adding: Pendulum.class (in=983) (out=607) (deflated 38%) adding: S_Euler.class (in=555) (out=349) (deflated 37%) adding: META-INF/ (in=0) (out=0) (stored 0%) adding: META-INF/MANIFEST.MF (in=70) (out=68) (deflated 3%) total bytes=1608, compressed=1024 -> 36% savings > time java -jar Pendulum.jar Pendulum 1.0,0.01 -0.926466004711948,-0.38103929142888787 0.7201228813478374,0.6974565073580707 -0.41054996704368263,-0.9138931625952093 0.04212461468187757,0.9993230097447542 0.33233931148399837,-0.9414996593503935 -0.6591623161707432,0.7487121028153431 0.8914942418259135,-0.44859648345965675 -0.996030250157117,0.08417444862477214 0.9577850788353137,0.2923140139811242 time=4969 5.111u 0.294s 0:06.77 79.7% 93+1127k 137+6io 83pf+0w > gcj42 -o pendulum.out --main=Pendulum Pendulum.java S-Euler.java ; time ./pendulum.out 1.0,0.01 -0.926466004711948,-0.38103929142888787 0.7201228813478374,0.6974565073580707 -0.41054996704368263,-0.9138931625952093 0.04212461468187757,0.9993230097447542 0.33233931148399837,-0.9414996593503935 -0.6591623161707432,0.7487121028153431 0.8914942418259135,-0.44859648345965675 -0.996030250157117,0.08417444862477214 0.9577850788353137,0.2923140139811242 time=9807 9.879u 0.031s 0:10.65 92.9% 10+1858k 0+0io 171pf+0w
Javaの方が2倍速い...
これじゃ,下手したらg++よりもJavaの方が速いんじゃないか?!
と思って,プログラムをC++用に書き換えてみました.そっくりですが,基底クラスはこんな感じです.
class S_Euler { public: double tau,p,q; S_Euler(double t, double p0, double q0) { tau = t; p = p0; q = q0; } virtual double f(double p, double q) = 0; virtual double g(double p, double q) = 0; void step() { p = p - tau*f(p,q); q = q + tau*g(p,q); } double get_p() { return(p); } double get_q() { return(q); } };
これをスーパークラスにしたサブクラスは,こんな感じです.
#include <iostream> #include <time.h> #include "S-Euler.cc" using namespace std; class Pendulum : public S_Euler { public: Pendulum(double t, double p, double q):S_Euler(t,p,q) { } double f(double p,double q) { return(q); } double g(double p,double q) { return(p); } }; int main(int argc, char *argv[]) { Pendulum a(0.01,1,0); clock_t start = clock(); for(int i=0;i<100000000;++i) { a.step(); if(i%10000000==0) { cout<<a.p<<","<<a.q<<endl; } } cout<<"time="<<((double)clock()-start)/CLOCKS_PER_SEC*1000.0<<endl; return(0); }
コンパイルして実行してみます.
> c++ -o pendulum.out Pendulum.cc ; time ./pendulum.out 1,0.01 -0.926466,-0.381039 0.720123,0.697457 -0.41055,-0.913893 0.0421246,0.999323 0.332339,-0.9415 -0.659162,0.748712 0.891494,-0.448596 -0.99603,0.0841744 0.957785,0.292314 time=6414.06 6.420u 0.007s 0:06.47 99.2% 5+1101k 0+0io 0pf+0w
...Javaの方が速いです.
c++のバージョンはこんな感じです.
> c++ -v Using built-in specs. Target: i386-undermydesk-freebsd Configured with: FreeBSD/i386 system compiler Thread model: posix gcc version 4.2.1 20070719 [FreeBSD]