Dhi*_*sen 8 c++ performance lambda inheritance virtual-functions
游戏引擎有这个类:
class MouseListener{
public :
MouseListener();
virtual void OnMouseDown(int mx,int my);
virtual void OnMouseUp(int mx,int my);
.
.
.
};
Run Code Online (Sandbox Code Playgroud)
每个想要监听鼠标输入的对象都必须固有该类并覆盖它的方法.为了不必每次都声明一个新类型,该类被修改为:
class MouseListener{
public :
MouseListener();
std::function <void(MouseListener*,int,int)>OnMouseDown;
std::function <void(MouseListener*,int,int)>OnMouseUp;
.
.
.
};
Run Code Online (Sandbox Code Playgroud)
现在使用这个类可以这样做:
MouseListener * m = new MouseListener();
m->OnMouseDown = [](MouseListener * thiz,int x,int y){
//// do something
};
Run Code Online (Sandbox Code Playgroud)
在输入系统中,只调用非空(已分配)的MouseListener函数(使用thiz =鼠标侦听器).知道该类是从外部库(静态链接)使用的,这在性能方面更好吗?
注意:除非收到鼠标事件,否则不会调用这些函数,当发生这种情况时,会为每个听取鼠标输入的对象调用相应的函数(不应该是批次,<50)
它实际上取决于虚函数与函数对象的用法.
虽然std::function 可能比虚拟调用*慢,但是std::function缓冲区优化很短,这可能会阻止动态内存分配(您可能在虚拟版本中进行分配).
这本身可能胜过你可能对常规多态性做的任何事情.
在内部(但不保证),std::function对象无论如何都使用虚拟调用进行类型擦除,所以我认为差异可以忽略不计.
提示 - 确保检查是否std::function有效(通过呼叫if(static_cast<bool>(myFunction))).编译器将插入一个检查以查看该函数是否为空.如果没有,该程序将抛出std::bad_function_call.开发人员检查将使编译器删除他的检查以及与std::bad_function_call何时启用优化相关的代码,从而留下更"平滑"的汇编代码.
在我的经验中处理性能和C++时,优化内存分配,线程间争用和错误的数据结构更加重要,这些结构对缓存起作用.通常,它比优化CPU的东西更有价值的优化(比如虚拟功能vs. std::function)
*一个不错的编译器可以将类型擦除实现为虚函数+给定的lambda作为内联函数.从理论上讲,它不应该比常规虚函数慢.另一方面,如果函数对象获得非可嵌入的可调用,如函数指针,它可以使用两个间接来启动该函数.这可能比常规虚拟呼叫慢.这取决于.