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