我有一些代码在我的C ++应用程序,一般不这样的:
bool myFlag = false;
while (/*some finite condition unrelated to myFlag*/) {
if (...) {
// statements, unrelated to myFlag
} else {
// set myFlag to true, perhaps only if it was false before?
}
}
if (myFlag) {
// Do something...
}
我的问题涉及到else
我的代码语句。 基本上,我的循环可以设置myFlag从虚假到真实的价值,根据一定的条件没有得到满足。 千万不要将国旗从真到假未设置。 我想知道是什么说法更有意义的性能代价,也许如果这个问题实际上是由于编译器优化一个非问题。
myFlag = true;
要么
if (!myFlag) myFlag = true;
我通常会选择前者,因为它要求写更少的代码。 不过,我开始怀疑,也许是涉及不用写入存储器,因此后者将防止不必要的写作myFlag已经如此。 但是,就使用后者需要更多的时间,因为有一个条件语句,因此使用更多的指令编译的代码?
或者,也许我过想这太...
更新1
我只想澄清一点...我的后一种情况的目的是为了不写入内存,如果变量已经如此。 因此,仅当该变量为假写入存储器。
你几乎可以肯定是最好只使用myFlag = true;
。
关于您可以从最好的希望if (!myFlag) myFlag = true;
是编译器会发现, if
是无关紧要的,并优化它拿走。 特别是, if
语句需要读取的当前值myFlag
。 如果值是不是已经在缓存中,这意味着该指令将停止在等待数据从内存中读取。
相反,如果你只写(而不先进行测试)的值可以写入到写队列,然后更多的指令可以立即执行。 你不会得到一个摊位,直到/除非你读myFlag的值(并假设它写后,在合理不久阅读,这很可能仍然是在缓存中,所以拖延将是最小的)。
你一定要明白的是,检查是没有实际意义吗? 如果你一味地将其设置为true
,并没有设置,你设置它。 如果已经是true
,那么有没有变化,你是不是 设置它,这样你就可以有效地实现它:
myFlag = true;
关于潜在的优化,才能够进行测试,该值必须在高速缓存中 ,所以大部分的费用已经支付。 在另一方面,分支(如果编译器不优化if
离开,其中大部分会)能有更大的性能影响。
CPU周期明智的,更喜欢myFlag = true;
想想看:即使编译器不做任何优化(不是真的有可能),只是设置它需要一个asm
语句,经历的if
需要至少1 asm
语句。
所以只要去分配。
更重要的是,不要试图让这种低层次的细节假设,具体的编译器优化可以完全违背直觉。
你最有可能过度思考这个问题已经提到别人,所以让我做相同的。 下面可能会更快,如果你能负担得起无关的声明一倍myFlag
。 事实上,你可以摆脱myFlag
。 OK,我们开始吧:
while (/*some finite condition*/) {
if (...) {
// statements
} else {
while (/*some finite condition*/) {
if (...) {
// statements, repeated
}
}
// Do something (as if myFlag was true in the OPs example)
break;
}
}
正如所有的性能优化:测量,测量,测量!
这是体系结构相关的是否if (!myFlag) myFlag = true;
将需要更多的时间比简单执行myFlag = true;
即使没有任何优化。 有结构(例如, https://developer.qualcomm.com/hexagon-processor )如双方声明将只需要一个周期的每个执行。
只有这样,才能弄清楚您的机器上出将是测量。
在任何情况下myFlag = true
总是会更快或具有相同的执行时间, if (!myFlag) myFlag = true;
这个问题让我头疼过,所以我只是用下面的代码(C#)测试它自己:
System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
int i = 0;
int j = 1;
time.Start();
if (i != 0)
i = 0;
time.Stop();
Console.WriteLine("compare + set - {0} ticks", time.ElapsedTicks);
time.Reset();
time.Start();
if (j != 0)
j = 0;
time.Stop();
Console.WriteLine("compare - {0} ticks", time.ElapsedTicks);
time.Reset();
time.Start();
i = 0;
time.Stop();
Console.WriteLine("set - {0} ticks", time.ElapsedTicks);
Console.ReadLine();
结果:
比较+设置 - 1个蜱
比较 - 1个蜱
设置 - 0刻度
而用来设定一定数值的时候,是不为零,它表明,即使单个查询需要的不仅仅是设定变量更多的时间。