C++ 函数性能问题
Posted
技术标签:
【中文标题】C++ 函数性能问题【英文标题】:C++ function performance issue 【发布时间】:2018-03-29 04:28:15 【问题描述】:我遇到了一个 ,使用下面的代码进行测试。 queryInterface
和 queryInterface1
的实现几乎相同。唯一的区别是queryInterface
调用classType
函数,而classType
函数调用classType1
,queryInterface1
直接调用classType1
。 queryInterface1
的性能很差,是queryInterface
的两倍。 queryInterface1
有什么问题,为什么?用 MSVC 编译。在控制台查看输出:
queryInterface() 的时间成本:2453
queryInterface1() 的时间成本:4961
#include <string>
#include <time.h>
#include <iostream>
#include <unordered_map>
using namespace std;
namespace
int find(const string& name)
return 0;
class A
public:
static int classType();
static int classType1();
virtual void* queryInterface(int id) const
if (A::classType() == id)
return const_cast<A*>(this);
return nullptr;
virtual void* queryInterface1(int id) const
if (A::classType1() == id)
return const_cast<A*>(this);
return nullptr;
;
int A::classType()
static int s_classType = classType1();
return s_classType;
int A::classType1()
static int s_classType = find("A");
return s_classType;
int main()
clock_t start, stop;
const size_t count = 1000000000;
A* pA = new A;
start = clock();
for (size_t i = 0; i < count; i++)
pA->queryInterface(A::classType());
stop = clock();
cout << "time cost of queryInterface(): " << stop - start << endl;
start = clock();
for (size_t i = 0; i < count; i++)
pA->queryInterface1(A::classType1());
stop = clock();
cout << "time cost of queryInterface1(): " << stop - start << endl;
return 0;
【问题讨论】:
你是怎么编译的?你启用优化了吗?find("A")
需要创建 std::string
对象,这会使调用变慢。
您是否多次运行每个版本?
FWIW,我在 cygwin 下看不到 g++ 6.4.0 的模式。
@S.M.,优化选项设置为“最大化速度 (/O2)”。两者都应该调用一次 find("A"),因为它是由静态变量调用的。
@John3136,是的,我运行它们 1000000000 次。
【参考方案1】:
性能差异是由于编译器在A::classType1
的调用中设置了安全检查。每次调用都会设置这些,即使它只在调用 find
函数的一次真正需要。
安全检查确定堆栈是否已被覆盖,可能会破坏堆栈帧,包括返回地址。
如果将s_classType
的初始值更改为常量整数,而不是调用find
,则可以更快地执行queryInterface1
调用。
可以使用/GS-
编译器选项禁用安全检查。
【讨论】:
你的意思是改变 A::classType1 如下?这不是更好。 int A::classType1() 静态 int s_classType = -1; if (s_classType == -1) s_classType = find("A"); 返回 s_classType; @ldlchina 不,我完全消除了对find
的调用(static int s_classType = 17;
)。您需要将对 find
的调用放入另一个函数中以避免异常处理程序的惩罚。
喜欢 A:classType?如果是这样,那让我很紧张,什么时候需要这样做?规则是什么?谢谢。 @1201ProgramAlarm
@ldlchina 是的,比如A::classType
。如果静态初始化表达式做了一些可能需要异常处理程序的事情,而函数的其余部分却不需要,那么你会想要这样做。
为什么A::classType()
不会发生这种情况?以上是关于C++ 函数性能问题的主要内容,如果未能解决你的问题,请参考以下文章