3

削除したいポインタのベクトルがありますが、ベクトルを反復処理してdelete各要素を呼び出すのは非常に遅いです。もっと速い方法はありますか?

残念ながら、仮想スーパークラスを使用しているため、ポインターを格納する必要があります。単純化すると、クラス構造は次のようになります。

class VirtualSuperClass
{
protected:
    SomeType m_someMember;
    // ...
public:
    virtual void doSomething() = 0;
};

class Subclass_1 : public VirtualSuperClass
{
protected:
    SomeType m_someSubclassMember;
    // ...
public:
    virtual void doSomething() { /* do something*/ }
};

class Subclass_2 : public VirtualSuperClass
{
protected:
    SomeType m_someOtherSubclassMember;
    // ...
public:
    virtual void doSomething() { /* do something else*/ }
}

私のメイン メソッドでは、スーパークラスのポインターのベクトルを入力し、doSomething()すべての要素に対して関数を呼び出します。

int main()
{
    std::vector<VirtualSuperClass*> vec;
    vec.push_back(new Subclass_1());
    vec.push_back(new Subclass_2());
    vec.push_back(new Subclass_2());
    vec.push_back(new Subclass_1());
    // and so on, about 40,000 elements (not really done with .push_back :) ) ...

    // this actually runs in an application loop
    for (size_t i = 0; i < vec.size(); i++)
    {
        vec[i]->doSomething();
    }

    // ...

    for (size_t i = 0; i < vec.size(); i++)
    {
        delete vec[i];     // <-- pretty slow for large number of elements
        vec[i] = NULL;
    }
    vec.clear();
    return 0;
}
4

3 に答える 3

6

あなたが探しているかもしれないことの1つは、割り当てたクラスのカスタムアロケータです。この方法で、メモリを小さな断片ではなく一括してシステムに効果的に取得および解放できます。おそらく、これが「全体的な」パフォーマンスを向上させる唯一の解決策です。システムを変更せずに(ボトルネックを考えると、これは確かに良い考えのように見えます;))。

于 2013-11-11T19:12:07.343 に答える
1

パフォーマンスを向上させる可能性のある別の方法は、一種のメモリ プールを使用することです。この方法では、前もって 1 つの大きな raw バッファーを割り当ててから、newそのバッファー内に個々のオブジェクトを配置します。

deleteこれにはパフォーマンスが向上する可能性があります。これは、各ポインターを破棄する必要がありますが、破棄はデストラクタをingではなく直接呼び出すことによって行われるためです。これにより、システムのメモリ マネージャーにアクセスする必要がなくなり、その回避によってパフォーマンスが向上する可能性があります。

ただし、このアプローチには重大な注意点があり、最も極端な場合以外はお勧めしません。警告の中には、自分の記憶を管理するという面倒な責任があります。

于 2013-11-11T19:17:48.300 に答える