我的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的值从false设置为true。永远不会将旗帜从真假转为虚假。我想知道哪种语句在性能方面更有意义,并且可能由于编译器优化而导致这个问题实际上不是问题。
myFlag = true;
OR
if (!myFlag) myFlag = true;
我通常会选择前者,因为它需要编写更少的代码。然而,我开始怀疑它可能涉及不必要的写入记忆,因此后者会阻止不必要的写作,如果myFlag已经是真的。但是,使用后者需要花费更多时间,因为有一个条件语句,因此使用更多指令编译代码?
或许我过分思考这个......
只是澄清一下......后一种情况的目的是如果变量已经为真,则不写入内存。因此,只有在变量为false时才写入内存。
答案 0 :(得分:11)
使用myFlag = true;
几乎肯定会更好。
关于if (!myFlag) myFlag = true;
所能提供的最好的一点是,编译器会发现if
无关紧要并将其优化掉。特别是,if
语句需要读取 myFlag
的当前值。如果该值尚未存在于缓存中,则表示在等待从内存中读取数据时指令将停止。
相比之下,如果你只是写(没有先测试),可以将值写入写队列,然后可以立即执行更多指令。除非你读取myFlag的值,否则你不会得到一个停顿(并且假设它在写入之后很快就会被读取,它可能仍然在缓存中,因此停止将是最小的。)
答案 1 :(得分:2)
你确实意识到支票没有问题吗?如果您盲目地将其设置为true
并且未设置,则您设置它。如果它已经true
,那么就没有任何变化,您 设置,因此您可以有效地将其实现为:
myFlag = true;
关于潜在的优化,为了能够测试,该值必须位于缓存中,因此大部分成本已经支付。另一方面,分支(如果编译器没有优化if
,那么大部分将会对性能产生更大的影响。
答案 2 :(得分:2)
CPU周期明智,更喜欢myFlag = true;
想一想:即使编译器没有进行优化(实际上不太可能),只需设置它就需要一个asm
语句,然后通过{{1至少需要1 if
个语句。
所以请完成作业。
更重要的是,不要试图对这些低级细节做出假设,特定的编译器优化可能完全违背直觉。
答案 3 :(得分:0)
你很可能像其他人已经提到的那样过度思考问题,所以让我也这样做。如果您能够将与myFlag
无关的语句加倍,则以下内容可能会更快。事实上,你可以摆脱myFlag
。好的,我们走了:
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;
}
}
与所有性能优化一样:测量,测量,测量!
答案 4 :(得分:0)
即使没有任何优化,if (!myFlag) myFlag = true;
是否比简单myFlag = true;
执行需要更多时间的架构。有一些体系结构(例如https://developer.qualcomm.com/hexagon-processor),其中两个语句每个只执行一个循环。
了解机器的唯一方法是通过测量。
在任何情况下,myFlag = true
总是会更快或执行时间与if (!myFlag) myFlag = true;
相同
答案 5 :(得分:0)
这个问题让我头疼,所以我只是用以下代码(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滴答
set - 0 ticks
虽然用于设置值的时间肯定不为零,但它表明即使是单个查询也需要比设置变量更多的时间。