C++ 功能开销

示例

std::function可能会导致大量开销。因为std::function具有[值语义] [1],所以它必须将给定的可调用对象复制或移动到其自身中。但是,由于它可以接受任意类型的可调用对象,因此它经常必须动态分配内存才能执行此操作。

一些function实现具有所谓的“小对象优化”,其中小类型(如函数指针,成员指针或状态很少的函子)将直接存储在function对象中。但是,即使只有可noexcept移动构造的类型,这也才有效。此外,C ++标准并不要求所有实现都提供一个。

考虑以下:

//头文件
using MyPredicate = std::function<bool(const MyValue &, const MyValue &)>;

void SortMyContainer(MyContainer &C, const MyPredicate &pred);

//源文件
void SortMyContainer(MyContainer &C, const MyPredicate &pred)
{
    std::sort(C.begin(), C.end(), pred);
}

模板参数将是的首选解决方案SortMyContainer,但让我们假设,无论出于何种原因,这都是不可能或不希望的。SortMyContainer不需要存储pred超出自己的要求。但是,pred如果分配给它的函子的大小很重要,则可以很好地分配内存。

function分配内存,因为它需要复制/移动到其中;function获得给定的可赎回权。但SortMyContainer不需要拥有可调用项;它只是引用它。所以function在这里使用是过大的;它可能是有效的,但可能并非如此。

没有标准库函数类型仅引用可调用对象。因此,必须找到替代解决方案,或者您可以选择承受开销。

而且,function没有有效的方法来控制对象的内存分配来自何处。是的,有采取的构造allocator,但[许多实现不正确地实现他们...甚至根本] [2]。

C ++ 17

不再使用的function构造函数是allocator该类型的一部分。因此,无法管理分配。

调用afunction也比直接调用内容要慢。由于任何function实例都可以容纳任何可调用对象,因此通过进行的调用function必须是间接的。调用的开销function大约是虚函数调用的顺序。