boost :: bind会导致开销吗?

时间:2011-05-05 08:48:53

标签: c++ boost bind overhead

我目前正在研究网络软件。它有一个主类server,它显然代表一个服务器实例。

server实例可以发送请求,并通过回调通知用户响应。

代码如下:

class server
{
  public:
    typedef boost::function<void (int duration)> callback_func;

    void send_request(endpoint& ep, callback_func cb);
};

现在让我们说,作为一个用户,我希望回调知道调用它的实例,我可以做以下事情:

void mycallback(const server& sv, int duration) { ... }

server sv;
sv.send_request("localhost", boost::bind(&mycallback, boost::ref(sv), _1));

但我想知道:有没有这样做的开销?对mycallback的呼叫是否比使用“常规”呼叫慢?

谢谢。

脚注:我当然可以将我的typedef更改为:typedef boost::function<void (const server& sv, int duration)> callback_func;,如果boost::bind导致任何重大开销,那可能就是我最终要做的事情。我想知道使用boost::bind

的成本意味着什么

4 个答案:

答案 0 :(得分:5)

当然会导致开销。它的作用是创建一个存储绑定参数的仿函数,并使用剩余的参数调用operator()。现在,这是重要的吗?我不知道,因为那只是一个字。提出1000万个请求并进行衡量。你是唯一可以判断这种开销是否对你很重要的人。

另外,我遇​​到了类似的问题。因为我不需要委托,所以我可以使用函数指针。但我发现了一个有趣的benchmark,它也提到了一些替代实现,所有这些实现都比boost::function具有更好的性能。这是以可移植性为代价的,在某些情况下是实施中的丑陋,非标准的黑客攻击(但是回报非常好)。

答案 1 :(得分:5)

boost::bind生成一个功能对象,如果它被用作函数模板的参数,可以对其进行优化,但是boost::function会阻止这种优化,就像传递指向函数的指针一样会阻止其内联。 boost::function本身不需要引入比虚函数更多的开销,也不需要通过函数指针调用。

PS。我同意TamásSzelei:提出1000万个请求并进行衡量。

答案 2 :(得分:2)

与普通函数调用相比,您为函数调用支付两个间接值,这类似于(非虚拟化)虚函数调用的开销。

第一个间接是由于boost :: function中发生的类型擦除(在boost::function文档中这是documented)。这个不能真正优化,你也可以使用裸函数指针同样处罚。

第二个间接来自通过函数指针调用mycallback函数。一个非常优化的编译器可以解决这个问题并优化它,但普通的编译器不会。如果将mycallback转换为函数对象,则可以摆脱这种间接(在所有编译器中):

而不是

void mycallback( .1. ) { .2. }
你做了

struct mycallback {
    void operator()( .1. ) const { .2. }
};

答案 3 :(得分:1)

请注意boost :: bind会导致仿函数的副本。这可能非常重要。对于我的操作系统,新闻和删除非常昂贵。请参阅关于ref()和cref()的boost :: bind文档。我相信成员函数也会导致仿函数副本,但没有相关的文档。