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

您可能正在寻找的一件事是您分配的类的自定义分配器 - 这样您可以有效地批量获取和释放系统内存,而不是小片段 - 这可能是提高“整体”性能的唯一解决方案系统而不修改它(这给你的瓶颈肯定看起来是个好主意;))。

于 2013-11-11T19:12:07.343 回答
6

任何正确的解决方案都归结为delete对每个指针执行 a 。由于您已经分析了您的代码并将其确定为瓶颈,因此我会寻找一种将其delete移至另一个线程的解决方案。

这可以通过以下方式完成:

  1. 创建一个工作线程,将deletes 指针传入
  2. 从向量中删除指针并将它们复制到另一个向量,由工作线程拥有
  3. 启动工作线程作业,让它删除指针

就纯 CPU 时间而言,这不会比您当前的解决方案更快(实际上可能会更慢,具体取决于您的操作方式),但它会将繁重的工作从主线程中移出。

于 2013-11-11T19:07:10.867 回答
1

另一种可能提高性能的方法是使用一种内存池,您可以在其中预先分配一个大的原始缓冲区,然后将new每个单独的对象放置在该缓冲区中。

这具有提高性能的潜力,因为尽管您仍然必须销毁每个指针,但该销毁是通过直接调用析构函数而不是deleteing 来完成的。这避免了必须使用系统的内存管理器,而这种避免是性能改进的潜力所在。

然而,这种方法有一些重要的警告,除了最极端的情况外,我不会推荐它。需要注意的是,您要承担管理自己记忆的繁重责任。

于 2013-11-11T19:17:48.300 回答