boost::bind会导致开销吗?

Does boost::bind cause overhead?

本文关键字:开销 bind boost      更新时间:2023-10-16

目前从事网络软件开发。它有一个主类,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的成本是多少

当然这会造成开销。它所做的是创建一个functor来存储绑定的形参,并有一个operator(),您可以用剩余的实参调用它。这有意义吗?我不知道,因为那只是一个词。提出1000万个请求并进行衡量。你是唯一一个知道这个开销对你是否重要的人。

我也遇到过类似的问题。因为我并不真正需要委托,所以我可以使用函数指针。但是我发现了一个有趣的基准测试,它也提到了一些替代实现,它们的性能都比boost::function好。这是以可移植性为代价的,并且在某些情况下,实现中出现了丑陋的、非标准的hack(但作为回报,却获得了非常好的性能)。

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

p。我同意Tamás Szelei的观点:提出1000万个请求并衡量它。

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

第一个间接是由于boost::函数中发生的类型擦除(这在boost::function文档中有记录)。这一点确实不能被优化,对于一个裸露的函数指针,你也会有同样的惩罚。

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

不是

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

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

请注意boost::bind会导致函数的复制。这是非常重要的。对于我的操作系统来说,更新和删除是非常昂贵的。参见boost::bind文档中有关ref()和cref()的信息。我相信成员函数也会导致函子复制,但是没有相关的文档。