作ってるゲームとは関係ないのだけど、
色情報と三次元座標情報を持つたくさんの点を管理する、
というプログラムが必要になったのです。
そこで最近C++のSTLを色々調べていたところなので、
その(個人的)ブームに乗ってSTLのvectorを使ってみたらどうかなーと思ってたところ…。
vectorは要素数が数万くらいになるとデータ構造がぶっ壊れる
みたいな話を聞いて、
うわーマジか数十万は点データ突っ込む予定なのに…と思いつつ
ちょっと本当なのか検証してみました。
以下はそのときのソースコードです。
新しく導入した
SyntaxHighlighterを試す意味でも。
#include
#include
#include
using namespace std;
// 点データ(RGBA, 三次元座標)
struct DATA {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
float x;
float y;
float z;
DATA(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a,
float _x, float _y, float _z)
: r(_r), g(_g), b(_b), a(_a), x(_x), y(_y), z(_z)
{}
};
// メイン
int main( int argc, char **argv ) {
// リスト作成
vector dataList;
dataList.reserve(1000000);
// 処理時間計測用
LARGE_INTEGER nFreq, nBefore, nAfter;
memset(&nFreq, 0x00, sizeof nFreq);
memset(&nBefore, 0x00, sizeof nBefore);
memset(&nAfter, 0x00, sizeof nAfter);
DWORD dwTime = 0;
float countF = 0.0f;
int count = 0;
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBefore);
while (1) {
try {
DATA data(0, 0, 0, 0, countF, countF, countF);
dataList.push_back(data); // データ追加
count++;
countF++;
if (count % (640 * 480) == 0) {
QueryPerformanceCounter(&nAfter);
dwTime =
(DWORD)((nAfter.QuadPart - nBefore.QuadPart) * 1000 / nFreq.QuadPart);
// データの入ってる要素数とメモリ確保してる要素数
cout << "dataList.size: " << dataList.size()
<< " dataList.capacity: " << dataList.capacity() << endl;
// データ追加(640 * 480 コ)にかかった時間
cout << dwTime << "ms.\n";
char c[2];
cin >> c;
if (c[0] == 'z')
break;
QueryPerformanceCounter(&nBefore);
}
}
catch (...) {
cout << "error!\n";
return -1;
}
}
for (size_t i = 0; i < dataList.size(); i += 1000) {
cout << (int)dataList[i].r << ", " << (int)dataList[i].g << ", "
<< (int)dataList[i].b << ", " << (int)dataList[i].a << endl;
cout << dataList[i].x << ", " << dataList[i].y << ", " << dataList[i].z << endl;
}
dataList.clear();
cout << "dataList.size: " << dataList.size()
<< " dataList.capacity: " << dataList.capacity() << endl;
int n;
cin >> n;
return 0;
}
環境はCPU: 2.27GHz, メモリ4GB, Windows7, VC++2008使用。
結局これで100万個程度要素を追加してみましたが、
データが壊れるということは起こっていないっぽい…。
要素数というよりは、データの大きさが関係しているのかもしれない。
ひとつの点データは1×4+4×3=16バイト。
それが100万個だと16MBか。
メモリは4GBあるので、それを思うとたいした量ではなさそう。
あと要素の追加にどれくらい時間がかかるのかと思って、計測してみました。
640×480個のデータ追加の10回平均が167ms。(Debugモードで)
最初にreserveしてなかったらもっとかかる。
メモリcapacityの拡大も一緒だと300msくらいだった。
ついでに同じことをvectorの代わりに配列を使ってやると約14msでやってくれた。
うむーやっぱり早さでは配列が勝るのか…。
結局わかったことは、
・要素数数万でvectorが壊れるということはなさそう(データの大きさによるとは思うが)
・要素数の上限がわかってるなら配列を使ったほうが良い。早い。
ですかなー。
ちなみにコンパイルをReleaseモードでやるとまたみちがえるほど早くなったのでござる。