【问题标题】:remove_if with boost::bind is slow带有 boost::bind 的 remove_if 很慢
【发布时间】:2013-02-23 01:25:59
【问题描述】:

我有一个 std::list 类并且想要删除标记为删除的条目。我正在使用 std::remove_if 和擦除。

class MyClass
{
    bool isDone(MyData& myData)
    {
        return myData.isDone();
    }

    void removeIfDone(std::list<MyData>& myList)
    {
        std::list<MyData>::iterator it =
            remove_if(myList.begin(), myList.end(), 
                  boost::bind(&MyClass::isDone, this, _1));
        myList.erase(it, myList.end());
    }
};

我在一个小型处理器上运行,它的内存分配和释放非常昂贵。此删除在我的应用程序中调用了数千次 new 和 delete。

我之前在传递非平凡变量作为绑定参数时使用了boost::ref,但在这种情况下,我认为可能是仿函数本身的创建和销毁或它的复制导致了问题。

我想做类似的事情

boost::bind(&MyClass::isDone, boost::ref(this), boost::ref(_1));

我找不到有关创建和销毁内容的文档。所以我的简单问题是如何提高效率?

【问题讨论】:

  • 您是否检查过std::vector&lt;std::unique_ptr&lt;MyClass&gt;&gt; 甚至std::vector&lt;MyClass&gt; 是否不比list 快?通常是
  • @andyt 谢谢你的建议。那是 4 年前的事了,我不再在那里工作,但我很确定我在使用列表,因为我需要列表的好处。

标签: c++ boost ref boost-bind remove-if


【解决方案1】:

尝试用std::list::remove_if 替换对std::remove_if 的调用。后者应该只从前面和后面的元素中复制一些指针,而不是尝试将元素移动到列表的末尾,这是您看到的多重分配的原因。另一个好处是,由于它是 std::list 的成员函数,它实际上会删除(即擦除)符合您的条件的元素。

class MyClass
{
    bool isDone(MyData& myData)
    {
        return myData.isDone();
    }

    void removeIfDone(std::list<MyData>& myList)
    {
        myList.remove_if( boost::bind( &MyClass::isDone, this, _1 ) );
    }
};

【讨论】:

  • +1 这是正确答案,boost::bind 完全不相关。
  • 优秀的答案。 boost::bind() 根本不应该影响速度(它只是语法糖)——正如你所指出的,真正的罪魁祸首是算法本身。
  • 在我们的系统上,这产生了 10 倍的差异。这让我意识到 库中的函数不仅是通用的——它们适用于多种容器类型——而且它们以一种可能不是最有效的通用方式操作容器。谢谢大家的帮助。
【解决方案2】:

您也许可以使用传递给std::remove_if 的简单函子来解决您的问题。这样您就不需要在remove_if 中向它传递任何参数并为自己保存一个boost::bind

struct functor
{
public:
    bool operator()(MyData& mydata)
    { 
       return mydata.IsDone();
    }   
};

void removeIfDone(std::list<MyData>& myList)
{
   std::list<MyData>::iterator it =
     remove_if(myList.begin(), myList.end(), 
         functor()); //call operator() on functor
     myList.erase(it, myList.end());
}

compiles here的例子

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多