vector と array の違い (C++) その2.

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[0] = 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 = 0; x < N; x++) {
    sh[x] = lh[x] = 0;
    for (int i = 9, t = x; i > 0; 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[0] = 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 = 0; x < N; x++) {
    sh[x] = lh[x] = 0;
    for (int i = 9, t = x; i > 0; 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(0) = 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 = 0; x < N; x++) {
    sh.at(x) = lh.at(x) = 0;
    for (int i = 9, t = x; i > 0; 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()を[]に変えられないのかなぁ.