31 c++ performance
类访问成员变量或局部变量更有效吗?例如,假设您有一个(回调)方法,其唯一的职责是接收数据,对其执行计算,然后将其传递给其他类.在性能方面,有一个成员变量列表更有意义,该方法在接收数据时填充?或者只是在每次调用回调方法时声明局部变量?
假设这种方法每秒会被调用数百次......
如果我不清楚,这里有一些简单的例子:
// use local variables
class thisClass {
public:
void callback( msg& msg )
{
int varA;
double varB;
std::string varC;
varA = msg.getInt();
varB = msg.getDouble();
varC = msg.getString();
// do a bunch of calculations
}
};
// use member variables
class thisClass {
public:
void callback( msg& msg )
{
m_varA = msg.getInt();
m_varB = msg.getDouble();
m_varC = msg.getString();
// do a bunch of calculations
}
private:
int m_varA;
double m_varB;
std::string m_varC;
};
Run Code Online (Sandbox Code Playgroud)
pet*_*hen 47
执行摘要:在几乎所有场景中,无关紧要,但局部变量略有优势.
警告:您正在进行微观优化.你最终会花费数小时试图理解本应该赢得纳秒的代码.
警告:在您的场景中,性能不应该是问题,而是变量的作用 - 它们是临时的,还是thisClass的状态?
警告:优化的第一,第二和最后一条规则:措施!
首先,看看为x86生成的典型程序集(您的平台可能会有所不同):
// stack variable: load into eax
mov eax, [esp+10]
// member variable: load into eax
mov ecx, [adress of object]
mov eax, [ecx+4]
Run Code Online (Sandbox Code Playgroud)
一旦加载了对象的地址,在寄存器中,指令是相同的.加载对象地址通常可以与先前的指令配对,并且不会达到执行时间.
但这意味着ecx寄存器不可用于其他优化.然而,现代CPU做了一些强烈的诡计,以减少问题.
此外,当访问许多对象时,这可能会花费额外的费用.然而,这不到一个周期平均值,并且配对指令通常有更多的机会.
记忆局部性:这是筹码赢得大时间的机会.堆栈顶部几乎总是在L1缓存中,因此负载需要一个周期.该对象更有可能被推回到L2缓存(经验法则,10个周期)或主存储器(100个周期).
但是,您只需为第一次访问付费.如果只有一次访问,则10或100个循环是不可察觉的.如果你有成千上万的访问,对象数据也将在L1缓存中.
总之,增益是如此之小,以至于将成员变量复制到本地以实现更好的性能几乎没有意义.
我更喜欢局部变量的一般原则,因为它们可以最大限度地减少程序中的恶变状态.至于性能,您的探查器会告诉您需要知道的所有信息.对于整数和其他内置函数,本地应该更快,因为它们可以放在寄存器中.
这应该是你的编译器问题。相反,优化可维护性:如果信息只在本地使用,请将其存储在本地(自动)变量中。我讨厌阅读充斥着成员变量的类,这些类实际上并没有告诉我关于类本身的任何信息,而只是关于一堆方法如何协同工作的一些细节:(
事实上,如果局部变量无论如何都不快,我会感到惊讶 - 它们必然在缓存中,因为它们接近其余的函数数据(调用帧)并且对象指针可能完全在其他地方 - 但是我只是在这里猜测。