資料館/E3Dの速度比較

Last-modified: 2009-04-06 (月) 01:06:33

E3D速度実験

おはようエンヂェル諸君。
testbox.jpg


こんな風に、箱を沢山発生させて表示するプログラムをHSPとC++で書いたからとりあえず俺の話を聞いてくれ。
*免責事項*
この実験レポートは俺が作ったプログラムで、私のパソコンでテストし、僕がレポートを書いています。
信憑性云々については自己責任でご覧下さい。一応、実行ファイルをうpっときます。

プログラムの概要

単純な四角錘を上下に張り合わせたモデルを用意した。コイツを仮に箱とでも名づけよう。コイツを200個生成し、壁との当たり判定を行いつつカメラ内をランダムな方向へ移動させる単純なプログラムだ。

箱モジュールの説明

箱は、HSPにおいてはモジュール型変数、C++においてはBoxClassとしてそれぞれ定義し、初期化時に200個の配列として用意している。(HSPならnewmod、C++の場合はnew演算子で)
この箱モジュールは、自身を移動させるmoveBOX,confWallなどのメンバ関数を持つ。参考までに汚いソースだがうpっておく。

#module
/*---------------------------------------------
コンストラクタ
---------------------------------------------*/
	#modinit int _cflag
	;ファイル読み込み
		E3Dsigload "..\\files\\box.sig",BoxID,1,1
		E3Daddmotion BoxID,"..\\files\\mot.qua",itmp1,itmp2,1
		e3dsetmotionkind BoxID,itmp1
	;初期位置の設定など
		Posx=0:Posy=rnd(1000):Posz=0
		E3DsetPos BoxID,Posx,Posy,Posz
		grav=0:weight=2+rnd(20)
		speed=10+rnd(50)
		cflag=_cflag
	;ランダムな方向へ回転させる
		E3DrotateY BoxID,rnd(360)
	return
/*---------------------------------------------
移動する命令
---------------------------------------------*/
	#modfunc MoveBox
		grav+=weight
		E3DgetPos BoxID,Posx,Posy,Posz


		if Posy<=0:{
			Posy=0
			grav=-((grav/5)*4)
		}
		Posy-=grav
		E3DSetPos BoxID,Posx,Posy,Posz
		E3Dposforward BoxID,speed

		if cflag!0:{;無意味な計算をする
			muimi=0
			repeat 1000
				muimi++
			loop
		}
	return
/*---------------------------------------------
壁との当たり判定を行う命令
---------------------------------------------*/
	#modfunc ConfWall int _WallID
		E3Dchkconfwall2 0,0,0,Posx,Posy,Posz,_WallID,100,resp,ax,ay,az,nx,ny,nz
		if resp=1:{;
			E3Dsetpos BoxID,ax,ay,az
			E3DrotateY BoxID,180
		}
	return
/*---------------------------------------------
描写を行う命令
---------------------------------------------*/
	#modfunc WriteBox int _scID,
		E3Dchkinview _scID,BoxID
		E3Drender _scID,BoxID,0,0,0,0,1,0
	return
#global

C++の方はめんどくさいので宣言だけで勘弁してくれ。
なるべく中身が同じになるようにしてある。

class BoxClass{
	int boxid;
	D3DXVECTOR3 boxpos;
	int grav;
	int weight;
	int speed;
	int muimi;
	int hitresult;
public:
	BoxClass();
	void moveBox();
	void confWall(int wallid);
	void writeBox(int scid);
};

また、プログラムは200個の箱を移動させ終える時間、及び描写し終わる時間、をミリ秒単位で計測し、表示する。

4つの実行ファイル

C++で作ったもの、HSPで作ったものそれぞれ二つずつ、計四つのファイルが出来上がった。
testbox.exeが通常のファイル、testbox_c.exeは無意味な計算フラグが有効になっているものである。
無意味な計算フラグとは、箱オブジェクトが実際にゲームを作る際に想定されるような、複雑な処理を抱えたオブジェクトに近づくんじゃないかと思ってとりあえずくっ付けたものである。このフラグが有効である場合、各ボックスは自分の移動処理のあと、自身のメンバ変数に0を代入し、それに1000回1を加算するという無駄な処理を行う。箱は200個生成されるので、この計算が1000回*200=200000回、毎フレーム行われる事となる。

testbox.exeの実行結果

この実行結果は、オイラのマシンで実行したものである。
あすろんの2GHz×2


右がHSP、左がC++
c-1.jpgh-1.jpg
testbox.exeは無意味な計算フラグがOFFであるため、必要最低限の動作を行う。描写速度、及び移動にかかる時間において、両者の差は微々たる物である。

testbox_c.exeの実行結果

右がHSP、左がC++
c-2.jpgh-2.jpg
今度はフラグが有効であるため、移動ルーチンに、1000回の無意味な演算が加わる。HSPにおいてはガックリとFPSが下がってしまった。相変わらず、両者の描写速度については大差はない。

結果のまとめ

  • C++、HSPにおいて両者の描写速度に余り違いは見られない。
  • オブジェクトの数が増える、複雑な処理を行うなど、描写速度以外の面で差が出てしまった
    • 逆に言えば、単純なプログラムにおいてC++を使うメリットは少ない。

総評

素人だからオラぁ良く判らんのだが、やはりCで作られているHSPがCより早く動く事はなかった。ゲームにおいてrepeat命令が増えれば増えるほど、ゲームはモリモリ重くなっていく事だろう。フレームスキップを安易に導入して描写処理をきった所で、他のところで時間を消費していては意味がない。我々HSPユーザーとしては、常に効率のいいっぽいスクリプトを書くことを意識する必要があるみたいれす。でもC++で開発するってのもいいと思うよ。今の時代、マイクソソフトさんがVC++2008タダでくれるし。


ただ、それほど差が出ないような単純なプログラムでC++を選択すると逆にめんどい。実験用のプログラムやゲームのサンプルを作ったりするなら、HSPを選択するべきである。また、派手なエフェクトを出したいというのは言語云々の問題ではないので、C++に移動しても解決しない。C++は解説書も豊富だしライブラリも豊富だし何も考えなくてもHSPより早いしクラス図描いてお友達と作ればハッピーハッピー*1という事でやりがいはあると思うが。

実行ファイル

自己責任でどうぞ
filetestbox.zip

まあインタプリタ言語とコンパイラ言語の速度を比較する事事態がナンセンスとも言えるが、僕が言いたいのは、用途に合わせて使おうよとそういう感じのアレ。


*1 注:多分に誇張を含む