4

std::vector は動的配列の薄いラッパーにすぎず、それらのパフォーマンスは同等であるという印象を受けました。インターネットとstackoverflow自体で検索しても、同じ答えが得られます。しかし、自分でテストすると、大きな違いが見つかりました。コードは以下です。最適化フラグ -O2 を使用して、VC++ 2012 (リリース ビルド) と MinGW の両方を試しました。

new、malloc、calloc の時間は約 0.005 秒ですが、std::vector は両方のコンパイラで 0.9 秒かかります。std::vector は本質的に遅いですか、それともコードに重大な欠陥がありますか?

#define _SCL_SECURE 0
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <time.h>

struct timer
{
    clock_t start;
    timer()
    {
        start=clock();
    }
    ~timer()
    {
        double t=static_cast<double>(clock()-start)/CLOCKS_PER_SEC;
        printf("%lf\n", t);
    }
};

int main()
{
    const size_t len=(1<<28);   
    {
        timer t;
        int *d=new int[len];
        printf("%d\n",d[len-1]);//prevent compiler from optimizing away 
                                //useless allocation and deallocation
        delete[] d;
    }
    {
        timer t;
        int *d=(int *)malloc(len*sizeof(int));
        printf("%d\n", d[len-1]);
        free(d);
    }

    {
        timer t;
        std::vector<int> d(len);
        printf("%d\n", d[len-1]);
    }
    {
        timer t;
        int *d=(int *)calloc(len, sizeof(int));
        printf("%d\n", d[len-1]);
        free(d);
    }

    return 0;
}

編集1

提案に従って、動的配列を作成する追加の方法をテストします

  • new:0.005
  • malloc:0.005
  • calloc:0.005
  • malloc+ memset: 1.244
  • vector(len): 1.231
  • vector(len, 0): 1.234
  • vector.reserve(len):0.005

したがって、実際に違反者は、割り当てまたは割り当て解除ではなくゼロ初期化です。vectorこれは、デフォルトですべての要素を初期化するコンストラクターがある場合でも、ゼロで初期化された配列が必要な場合に行くべきではないことを意味します。

それに、これは私の頭から飛び出すだけのものではありません。クラスの最終的なプロジェクトは、費やされた時間に基づいて評価されます。例外の安全性のためではvectorなく、巨大なメモリ バッファーを割り当てるために数秒を使用しました。これは、教科書で STL の使用が推奨されているためです。newこれが原因でポイントを失ったことに今日まで気づきませんでした。悲しい日。

編集2

今日、Ubuntu 13.04 x64 で Clang 3.2 を試してみたところ、std::vector の初期化に時間がかからなくなりました。実際、ベクトルは現在最速です! おそらく、これはコンパイラの最適化の問題であり、本質的に std::vector の設計に問題があるわけではありません。

4

2 に答える 2