2014年4月23日水曜日

C++: 動的なプロパティーシステムその2、mapのキー型にstringを使わずにunsignedを使ったら全体の処理速度に有意差は得られるか

前回の記事の続きみたいな記事です。

前回の記事では、「できるだけ動的なプロパティーシステムのみに頼らない方が圧倒的にパフォーマンス的なメリットがC++では得られるよ、でも動的なキーの追加と削除が可能なプロパティーシステムをゲームオブジェクトに実装したいのならstd::map<std::string, boost::any>とか使っておけばいいと思うよ」と言った内容でした。

今回は前回の記事で気になっていた「動的なプロパティーシステムにstd::mapを採用する場合にキー型をstd::stringではなくunsignedにしたなら、全体の処理速度に有意差を得られるだろうか」について確認しました。

例によって先に結論:

動的なプロパティーシステムのキー型をstd::stringではなくunsignedにする事で全体の処理速度に有意差を確認できる。

今回の例のような数千個のオブジェクトに対してニュートンの運動方程式をオイラー法でシミュレートするような使い方は現在のアクションゲームやシューティングゲームの基礎的なオブジェクトの運動で、実際にはより複雑で精度の高い(プロパティーの数や参照回数が多くなる)手法を用いたり、当たり判定の処理やその他アレコレの処理がプロパティーを使います。すると、つまり、この有意差はより大きく現れてしまうと推量されます。

今回はゲームオブジェクトのクラスにstatic constexprでテーブル的なものを持たせましたが、実際のところは1つのゲーム全体で共通の大きなテーブルで管理しないと値の重複で思わぬバグを誘発したりするかもしれませんし、実行時にスクリプトで追加されるキーについてはC++側で予め定数を用意し得ない場合もあり、そうなるとスクリプト側でテーブルを保持するか、数値をスクリプトから直接打ち込むのか…。どうも微妙な雰囲気ではあります。

さて、加えて、これはおまけ程度の有意差ではありますが、std::mapとstd::unordered_mapではunsignedキーの場合に有意差がわずかに見られるようです。mapがキー値の比較をそのまま比較演算子で行うのに対して、unordered_mapではハッシュ関数を噛ませます。unsigned値をstd::hashに通した結果は入力値そのままのはずではありますが、実行時の若干のオーバーヘッドになっているのかもしれません。それとデータ構造もバケットを噛ませる分オーバーヘッドになっているのかも。

ソースと結果:

0 件のコメント:

コメントを投稿