我一直在听这句话。Switch..Case对于代码维护是有害的,但它提供了更好的性能(因为编译器可以内联东西等)。虚函数非常适合代码维护,但它们会导致两个指针间接的性能损失。
假设我有一个基类,包含两个子类(X和Y)和一个虚拟函数,因此将有两个虚拟表。该对象有一个指针,它将根据该指针选择一个虚拟表。所以对于编译器来说,它更像是
switch( object's function ptr )
{
case 0x....:
X->call();
break;
case 0x....:
Y->call();
};既然编译器可以在这里做同样的内联和其他事情,那么为什么虚函数的成本会更高,如果它可以这样实现的话。或者解释一下,为什么决定不以这种方式实现虚函数执行?
谢谢,Gokul。
发布于 2010-03-09 09:40:03
由于独立的编译模型,编译器无法做到这一点。
在编译虚函数调用时,编译器无法确定有多少不同的子类。
考虑下面的代码:
// base.h
class base
{
public:
virtual void doit();
};还有这个:
// usebase.cpp
#include "base.h"
void foo(base &b)
{
b.doit();
}当编译器在foo中生成虚拟调用时,它不知道基类的哪些子类将在运行时存在。
发布于 2010-03-09 10:03:00
您的问题基于对交换机和虚拟函数工作方式的误解。我将给出几个要点,而不是用一篇关于代码生成的长篇论文来填满这个方框:
发布于 2010-03-09 12:17:25
以下是一些具体测试的结果。这些特定的结果来自VC++ 9.0/x64:
Test Description: Time to test a global using a 10-way if/else if statement
CPU Time: 7.70 nanoseconds plus or minus 0.385
Test Description: Time to test a global using a 10-way switch statement
CPU Time: 2.00 nanoseconds plus or minus 0.0999
Test Description: Time to test a global using a 10-way sparse switch statement
CPU Time: 3.41 nanoseconds plus or minus 0.171
Test Description: Time to test a global using a 10-way virtual function class
CPU Time: 2.20 nanoseconds plus or minus 0.110在稀疏情况下,switch语句的速度要慢得多。在密集的情况下,switch语句可能会更快,但switch和虚拟函数分派会有一些重叠,因此,虽然switch可能更快,但差距很小,我们甚至不能确定它是否更快,更不用说足够快了。如果switch语句中的情况是稀疏的,那么虚函数调用将会更快这一点是毫无疑问的。
https://stackoverflow.com/questions/2406060
复制相似问题