Container classes, C++ FAQ

によると,生のarrayより,vectorを使ったほうがベターだそうです.

理由としては

  • より生産定期になる
  • ロバストなコードになる
  • 他人がメンテしやすい
  • vetorにはat()がある(out of bounds を検知)
  • メモリ管理が楽
  • インサートしたりできる
  • 値渡し,参照渡しの選択ができる
  • 戻り値にできる

at()でout of boundsを検知できるのは知らなかった.

経験上,かなりの(自分の)バグがout of bounds関係なので,これは便利かも.

で,気になるのが,速度はどうなの?って質問.

ということで,実際のコードで試してみた.

コードは某 proj*ct eul*r 254 の一部.

結論から言うと(今回の実験では),生のarrayは速い.vectorの[]とat()は,ほぼ同じ.

以下,コード.違いは array か vecotr, [] か at()だけ.

array

g++ -O2 でコンパイル.実行時間 約 1.6 秒.

#include <iostream>
#include <boost/timer.hpp>
using namespace std;
int main() {
boost::timer t;
int fac[10];
fac[] = 1;
for (int i = 1; i < 10 ; i++) fac[i] = i * fac[i-1];
const int N = 1 << 24;
int (* dh)[10] = new int[N][10], (* sh) = new int[N], (* lh) = new int[N];
for (int x = ; x < N; x++) {
sh[x] = lh[x] = ;
for (int i = 9, t = x; i > ; i--) {
dh[x][i] = t / fac[i];
sh[x] += i * dh[x][i];
lh[x] += dh[x][i];
t %= fac[i];
}
}
cout << "elapsed: " << t.elapsed() << " second" << endl;
}

vector, []

g++ -O2 でコンパイル.約 3.3秒.

#include <iostream>
#include <vector>
#include <boost/timer.hpp>
using namespace std;
int main() {
boost::timer t;
vector<int> fac(10);
fac[] = 1;
for (int i = 1; i < 10 ; i++) fac[i] = i * fac[i-1];
const int N = 1 << 24;
vector< vector<int> > dh(N, vector<int>(10));
vector<int> sh(N), lh(N);
for (int x = ; x < N; x++) {
sh[x] = lh[x] = ;
for (int i = 9, t = x; i > ; i--) {
dh[x][i] = t / fac[i];
sh[x] += i * dh[x][i];
lh[x] += dh[x][i];
t %= fac[i];
}
}
cout << "elapsed: " << t.elapsed() << " second" << endl;
}
vector, at()

g++ -O2 でコンパイル.約 3.3秒.

#include <iostream>
#include <vector>
#include <boost/timer.hpp>
using namespace std;
int main() {
boost::timer t;
vector<int> fac(10);
fac.at() = 1;
for (int i = 1; i < 10 ; i++) fac.at(i) = i * fac.at(i-1);
const int N = 1 << 24;
vector< vector<int> > dh(N, vector<int>(10));
vector<int> sh(N), lh(N);
for (int x = ; x < N; x++) {
sh.at(x) = lh.at(x) = ;
for (int i = 9, t = x; i > ; i--) {
dh.at(x).at(i) = t / fac.at(i);
sh.at(x) += i * dh.at(x).at(i);
lh.at(x) += dh.at(x).at(i);
t %= fac.at(i);
}
}
cout << "elapsed: " << t.elapsed() << " second" << endl;
}

at()はout of bounds検知してくれるのは,いいんだが,コードが読みにくいなぁ.

at()を[]に変えられないのかなぁ.