C ++:仅在未设置时设置bool值

时间:2013-02-22 22:00:05

标签: c++ boolean variable-assignment conditional-statements compiler-optimization

我的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已经是真的。但是,使用后者需要花费更多时间,因为有一个条件语句,因此使用更多指令编译代码?

或许我过分思考这个......


更新1

只是澄清一下......后一种情况的目的是如果变量已经为真,则不写入内存。因此,只有在变量为false时才写入内存。

6 个答案:

答案 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

虽然用于设置值的时间肯定不为零,但它表明即使是单个查询也需要比设置变量更多的时间。