How expensive is to copy an std::function?

微笑、不失礼 提交于 2020-08-06 10:33:30

问题


While std::function is movable, in some cases it's not possible or not convenient. Is there a significant penalty for copying it?

Does it possibly depend on the size of the captured variables (if it was created using a lambda expression)? Is it implementation dependent?


回答1:


It is indeed implementation-dependent. It also depends on what exactly you are storing in the std::function. It is surely not as cheap as simply copying a C-style function pointer.

The best thing would be for you to try writing the code the way you find clear and convenient, then, if it does not run quickly enough, profile it. If you need ultimate performance, you may find std::function is not suitable at all.




回答2:


std::function is typically implemented as a value-semantics, small-buffer optimized, virtual-dispatch, type-erasing class.

This means if your state is small, a copy will involve no heap allocation (other than within the copy ctor of the state) and some indirection (to find how to copy this particular state).

If your state is large (larger than two std::strings on current MSVC, for example), it requires an additional heap allocation to store the state.

This is not something you want to do on a per-pixel per-frame basis, but it isn't insanely expensive.

How your particular compiler and library version implements std::function could vary, but I am unaware of any that differs significantly from the above.

So, in the following code:

std::function<std::string()> f = [s = "hello"s]{ return s; };

copying f will involve 0 heap allocations on MSVC.

Whereas, this code:

std::function<std::string()> g = [a = "a"s, b = "b"s, c = "c"s]{ return a+b+c; };

does require a heap allocation to copy g.

(And yes, both of these are really dumb function objects.)

There is an effective requirement that the small buffer optimization (SBO) be applied for certain cases (function pointers, member function pointers) in std::function by the fact that they are expected not to fail at allocating memory. Once you have written one SBO case, making it more general isn't hard, so most std::function implementations store small objects "inside themselves" and larger objects on the heap.

However, this threshold is not specified by the standard, and it is important for the performance cost, so if performance is really important, you'll have to profile to ensure that your implementation does it.



来源:https://stackoverflow.com/questions/44388849/how-expensive-is-to-copy-an-stdfunction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!