0

私は、ヒープにメモリを割り当てる単純なバージョンのベクトルで gprof を使用してテストを実行してきました (実際には動的ではありません - テスト目的のみ)。問題は、結果を見ると、「new []」と「delete []」の間に大きな違いがあることがわかります-実際にベクトルに値を挿入すると([]演算子を使用)。上記を実行すると、次のような結果が得られました。

%   cumulative   self              self     total           
  time   seconds   seconds    calls   s/call   s/call  name    
  0.92      0.55      0.01        1     5.03     5.03  MyVector::~MyVector()
  0.00      0.55      0.00        1     0.00     0.00  MyVector::MyVector(int)

しかし、実際にベクトルに値を挿入せずにメモリを割り当てて削除すると、同じように高速に動作します。

%   cumulative   self              self     total           
time   seconds   seconds    calls  ms/call  ms/call  name    
0.00      0.09     0.00        1     0.00     0.00  MyVector::MyVector(int)
0.00      0.09     0.00        1     0.00     0.00  MyVector::~MyVector()

私の推測では、'new[]' を使用する場合、コンパイラ (私の場合は gcc) は実際にはメモリを割り当てず、必要な場合にのみメモリを割り当てます ([] を使用する場合など)。また、オブジェクトを破棄する必要がある場合は、各アクセス中に割り当てられたすべてのメモリの割り当てを解除する必要があります ([] を使用)。

これに関するドキュメントが見つかりませんでした。おそらく、私が気付いていないことがあります。誰かがこの問題に関する彼の知識を共有してくれれば幸いです。

編集:使用したコードを追加しました。これまでのすべての回答に感謝します:

class MyVector
{
public:

        MyVector(int size) { _data = new int[size]; };
        ~MyVector() { delete[] _data; } ;

        int& operator[](int index) { return _data[i]; };

 private:
       int* _data;
       int _size;     
 };


    And the test:

int main() {

      MyVector v(1000000);

      for (int j = 0 ; j<20000 ; ++j) {
        for (int i = 0; i<1000000; ++i) {
          v[i]= i; //If i remove this line, destructor and constructor work just as fast
        }
     }

      return 0;
}
4

1 に答える 1

1

あなたは正しいです。new[]すべてのシステムでメモリをすぐに割り当てるわけではありません。たとえば Linux では、実際に使用しようとした場合にのみ割り当てられるメモリを指すポインターが返されます。そう:

something = new[N];
delete[] something;

wheresomethingは組み込み型へのポインターであり、ほとんどノーオペレーションです。

(これは標準への準拠に違反している可能性があります。これnewは、使用可能なメモリがなくなるとスローされる (または、非スロー バージョンでは NULL が返される) ことになっているためです。しかし、実際にはそうです。Linux は、これを無限のメモリがあるかのように扱います。)

これは組み込み型にのみ適用されることに注意してくださいnew[]。要求しない限り、組み込み型は でデフォルト構築されないためです。他のタイプにはデフォルトの ctor が呼び出されるため、メモリがアクセスされます。テストするには、最後の要素にアクセスしてみてください。

something = new[N];
something[N-1] = some_Value;
delete[] something;

これにより gprof の結果が変わりますか? はいの場合、割り当ての遅延が原因である可能性が最も高いです。

于 2013-01-17T12:02:41.690 に答える