vectorのメモ その1

C++vector使っててちょっと気づいたことのメモ。
タイトルにその1とかついてるけどまたなんかあったらその2とか作るかもしれないからです。

VisualStudioのDebugビルドだとvectorのアクセスは遅い

saxpyをやってみて比較してみました。
saxpyというのは
数式で表すと
Y = a * X + Y
となります。(Y,Xはベクトル、aはスカラ)
単精度の場合はsaxpyですが倍精度の場合はdaxpyと言ったりします。


問題サイズ(要素数)は10000000です。

最適化オプションなし

Debugビルド Releaseビルド
配列 0.0202452(秒) 0.0236787(秒)
vector 0.827819(秒) 0.0493195(秒)

Debugビルド時にvectorがものすごく遅いのがわかります。
Releaseビルドでは使えるレベルですが、配列を使た時の半分の性能しか出ていません。

Releaseビルドでは最適化を行うと思うので、VSのO2オプションをつけて計測してみました。
O2オプション

Releaseビルド
配列 0.00778593(秒)
vector 0.00793234(秒)

ちゃんと最適化を行えば配列もvectorもあまり大差ない結果になるみたいです。


同様の実験をg++でもやってみました。
上述のものとは違う端末を使っているので速度は上のものとは異なっています。

g++

最適化なし O3
配列 0.0412589(秒) 0.0097611(秒)
vector 0.080672(秒) 0.0137689(秒)


最適化オプションなしの場合でも、最適化オプションをO3にした場合でもvectorが遅くなっているのがわかります。

vectorって便利ですがやはり配列よりは遅いんですかね。

vectorの2次元配列は連続メモリ配列にならない

意外と忘れてしまったまま使いそうなので一応メモ。

vectorの2次元配列を作る場合に、次のような書き方をすることがあると思います。

vector< vector<float> > array(10, vector<float>(10));

こうすることで10*10の二次元配列ができるわけですがメモリ連続にはなりません。

解決策としては
1次元配列を2次元配列のように使えば大丈夫ですね。
実際この方法を使うのが多いかもです。
10*10のvectorを作りたい場合は

vector<float> array(10*10);

のように必要なサイズを1次元配列でとってしまいます。
アクセスするときは
たとえば3行目0列目にアクセスしたいときは
array[3*10 + 0]
5行目8列目にアクセスしたいときは
array[5*10 + 8]
といった感じにアクセスできます。

もう一つの解決策としては
boostライブラリのboost::multi_arrayなどを使えばメモリ連続に領域確保もでき、array[i][j]のようなアクセスも可能になります。

まとめ

vectorは配列よりも遅い
・VisualStudioを使うときはDebugビルドだとかなり遅い
vectorの二次元配列はメモリ連続にならない
  解決策としては
    ・1次元配列で一括で領域を確保して2次元配列のように扱う
    ・boostライブラリのboost::multi_arrayを使う