快速删除指针的 STL 向量条目的方法

fast way to delete entries of STL vector of pointers

本文关键字:方法 向量 STL 删除 指针      更新时间:2023-10-16

我有一个想要删除的指针向量,但是遍历向量并为每个元素调用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*/ }
}

在我的 main 方法中,我填充超类的指针向量,并为每个元素调用函数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;
}
您可能

正在寻找的一件事是您分配的类的自定义分配器 - 这样您就可以有效地批量获取和释放内存到系统,而不是以微小的片段 - 这可能是在不修改它的情况下提高该系统的"整体"性能的唯一解决方案(鉴于您的瓶颈确实看起来像一个好主意;))。

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

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

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

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

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

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

然而,这种方法有一些重要的警告,除了最极端的情况,我不建议这样做。 其中需要注意的是,你给自己施加了管理自己记忆的繁重责任。