[解決済み】std::vectorは普通の配列よりそんなに遅いの?
質問
というのが一般的な常識だと思っていました。
std::vector
は、配列として実装されています。今日、私はそれをテストし、そしてそれはそうではないようです。
以下はテスト結果です。
UseArray completed in 2.619 seconds
UseVector completed in 9.284 seconds
UseVectorPushBack completed in 14.669 seconds
The whole thing completed in 26.591 seconds
約3~4倍も遅いんですね~。これでは「quot」の意味がありません。
vector
may be slower for a few nanosecs" というコメントがあります。
そして、使ったコード。
#include <cstdlib>
#include <vector>
#include <iostream>
#include <string>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/microsec_time_clock.hpp>
class TestTimer
{
public:
TestTimer(const std::string & name) : name(name),
start(boost::date_time::microsec_clock<boost::posix_time::ptime>::local_time())
{
}
~TestTimer()
{
using namespace std;
using namespace boost;
posix_time::ptime now(date_time::microsec_clock<posix_time::ptime>::local_time());
posix_time::time_duration d = now - start;
cout << name << " completed in " << d.total_milliseconds() / 1000.0 <<
" seconds" << endl;
}
private:
std::string name;
boost::posix_time::ptime start;
};
struct Pixel
{
Pixel()
{
}
Pixel(unsigned char r, unsigned char g, unsigned char b) : r(r), g(g), b(b)
{
}
unsigned char r, g, b;
};
void UseVector()
{
TestTimer t("UseVector");
for(int i = 0; i < 1000; ++i)
{
int dimension = 999;
std::vector<Pixel> pixels;
pixels.resize(dimension * dimension);
for(int i = 0; i < dimension * dimension; ++i)
{
pixels[i].r = 255;
pixels[i].g = 0;
pixels[i].b = 0;
}
}
}
void UseVectorPushBack()
{
TestTimer t("UseVectorPushBack");
for(int i = 0; i < 1000; ++i)
{
int dimension = 999;
std::vector<Pixel> pixels;
pixels.reserve(dimension * dimension);
for(int i = 0; i < dimension * dimension; ++i)
pixels.push_back(Pixel(255, 0, 0));
}
}
void UseArray()
{
TestTimer t("UseArray");
for(int i = 0; i < 1000; ++i)
{
int dimension = 999;
Pixel * pixels = (Pixel *)malloc(sizeof(Pixel) * dimension * dimension);
for(int i = 0 ; i < dimension * dimension; ++i)
{
pixels[i].r = 255;
pixels[i].g = 0;
pixels[i].b = 0;
}
free(pixels);
}
}
int main()
{
TestTimer t1("The whole thing");
UseArray();
UseVector();
UseVectorPushBack();
return 0;
}
私のやり方が悪いのか、それとも何か?それとも、このパフォーマンス神話を打ち破ったのでしょうか?
でリリースモードを使っています。 ビジュアルスタジオ2005 .
で
ビジュアル C++
,
#define _SECURE_SCL 0
削減
UseVector
を半分にする(4秒にする)。これは本当に大きいです、IMO。
解決方法は?
以下を使用します。
<ブロッククオート
g++ -O3 Time.cpp -I <MyBoost>
./a.out
UseArrayの実行時間:2.196秒
UseVector 4.412秒で完了
UseVectorPushBackの実行時間:8.017秒
全体が完了したのは14.626秒
つまり、arrayはvectorの2倍速いということですね。
しかし
ベクトルは2回、配列は1回だけなので、これは予想通りです。注
resize()
ベクトルでは、メモリを確保するだけでなく、ベクトル内を移動して各メンバーのコンストラクタを呼び出しています。
コードを少しアレンジして、ベクターが各オブジェクトを一度だけ初期化するようにします。
std::vector<Pixel> pixels(dimensions * dimensions, Pixel(255,0,0));
今、もう一度同じタイミングを行う。
g++ -O3 Time.cpp -I <MyBoost>
./a.out
UseVectorの実行時間:2.216秒
vectorはarrayよりほんの少しパフォーマンスが悪くなりました。IMO この差は重要ではなく、このテストに関連しない多くの事柄が原因である可能性があります。
のPixelオブジェクトを正しく初期化/破棄していないことも考慮に入れます。
UseArrray()
メソッドが呼び出されないためです。(この単純なクラスでは問題ないかもしれませんが、もう少し複雑なもの(たとえばポインタやポインタを持つメンバー)では問題が発生するでしょう。
関連
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] B "の印刷が "#"の印刷より劇的に遅いのはなぜですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] std::vector にある項目が存在するかどうかを調べるには?
-
[解決済み] std::vectorをハードコードされた要素で初期化する最も簡単な方法は何ですか?
-
[解決済み] std::vector<> からインデックスで要素を消すにはどうしたらいいですか?
-
[解決済み] std::vector に対する反復処理: 符号なしインデックス変数と符号ありインデックス変数の比較
-
[解決済み] C++におけるstd::vectorとstd::arrayの比較
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】'cout'は型名ではない
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】C++で配列とstd::vectorの使い分け、性能の差は何?