有快速代理背后的想法(等人)被用于优化的std ::功能?(Have the ideas behin

2019-06-25 15:03发布

一直以来都有C ++“代表”这比低开销的建议boost::function

  • 成员函数指针和最快的C ++委托
  • 快速的C ++委托
  • 该难以置信的快C ++代表

有任何这些想法被用来实现std::function ,从而更好的性能比boost::function ? 有没有人相比的性能std::function VS boost::function

我想专门为GCC编译器和libstdc ++基于英特尔64位架构知道这一点 ,但在其他的编译器的信息是值得欢迎的(如锵)。

Answer 1:

在的libstdc ++的std::function ,我们使用的联合类型是合适尺寸和对准,以存储指针,函数指针或指针成员函数。 我们避免可存储在大小和对齐任何函数对象堆分配, 只有当它是“位置不变”

/**
 *  Trait identifying "location-invariant" types, meaning that the
 *  address of the object (or any of its members) will not escape.
 *  Also implies a trivial copy constructor and assignment operator.
 */

该代码是基于std::tr1::function的实现和部分没有显著改变。 我认为,可以用简化std::aligned_storage并且可以通过专业,让更多的类型确定为位置不变的性状得到改善。

调用没有任何虚拟函数调用完成目标对象,该类型擦除通过存储在一个单独的函数指针进行std::function是一个函数模板特的地址。 所有操作都通过调用通过存储的指针函数模板,并传递一个枚举识别它被问什么要执行的操作来完成。 这意味着,没有虚函数表和仅需要被存储在对象中的单个函数指针。

这种设计的贡献原来boost::function作者,我相信这是靠近提升执行。 请参阅性能为来自Boost.Function文档的一些基本原理。 这意味着,这是非常不可能的GCC的std::function是任何速度比boost::function ,因为它是一个类似的设计由同一人。

NB我们std::function不支持建设与分配器的是,它需要做任何的分配将利用做new


在回应埃米尔的评论表示以避免对堆分配的欲望std::function ,其保存成员函数指针和对象,这里有一个小黑客这样做(但你没有听到我的心声;-)

struct A {
  int i = 0;
  int foo() const { return 0; }
};

struct InvokeA
{
  int operator()() const { return a->foo(); }
  A* a;
};

namespace std
{
  template<> struct __is_location_invariant<InvokeA>
  { static const bool value = true; };
}

int main()
{
  A a;
  InvokeA inv{ &a };

  std::function<int()> f2(inv);

  return f2();
}

诀窍是, InvokeA足够小,以适应function的小物件缓冲区和特质专业化说,它是安全的存储在那里,所以function直接持有该对象的副本,而不是在堆上。 这需要a ,只要它坚持坚持为指针,但如果将反正是这样function的目标是bind(&A::foo, &a)



Answer 2:

正如在评论中指出,性病::功能只有一个接口,不同的实现可以做不同的事情,但它是值得一提的是,标准没有真正有话要说这件事。 从20.8.11.2.1 / 5(其看起来更像比标准的一部分的IP地址):

注意:在实行中,避免小可调用的对象的使用动态分配的内存,例如,其中f的目标是一个对象只持有的指针或引用一个对象和一个成员函数指针。 末端笔记

这是令人鼓舞的实施者采用“小功能优化,”这是通过对代表们引用的文章动机的标准的方式。 (文章本身并没有真正谈论在.NET意义的代表,相反,他们使用的术语“代表”的意思绑定的成员函数)。



文章来源: Have the ideas behind the Fast Delegate (et al) been used to optimize std::function?