【问题标题】:Does checking constant TRUE or FALSE take much operational time?检查常量 TRUE 或 FALSE 是否需要很多操作时间?
【发布时间】:2021-01-11 17:47:59
【问题描述】:

以一个搜索算法为例,假设它是一个顺序搜索算法。他们说程序检查的条件越少,算法就越快。这里的条件被认为是一些值之间的比较(例如检查值的相等性)。也就是说,如果一个程序中有比较,它确实会影响程序的性能。而且这些比较的次数越多,程序终止的时间就越长。

while(comparison)
{body;}

但我想知道如果没有比较作为条件和一些文字表达式,程序会如何表现,例如:

while(TRUE)
{body;}

问题是:如果按性能进行估计,文字条件和比较条件有何不同?

为了让这个问题更清楚,请考虑以下代码:

while(condition)
{body;}

while(TRUE)
{        
    if (condition) break;
    body;
}

也许第三个也很接近第二个:

char done = 0;
while (!done)
{        
    if (condition) done++;
    else body;
}

如果最快的是哪一个?第二个和第三个的处理速度比第一个慢吗?

【问题讨论】:

  • 由于这两段代码根本不等价,我不确定这是一个有意义的比较。是的,第二段代码会更快。它也不起作用。
  • 你真的是在比较 while (condition) { body; }while (1) { if (!condition) break; body; },对吧?
  • @pmg 是的,这更合理,我会编辑帖子
  • 第三个和另外两个不同,必须是while (!done) { if (condition) { done++;} else { body; }}
  • @mevets 对,已编辑

标签: c performance conditional-statements


【解决方案1】:

通常,如果编译器可以在编译时确定条件,它会生成一个“总是分支”指令,它本身比“设置分支”/“如果相等则分支”等稍快。

但更重要的是,“总是分支”意味着 CPU 的分支预测功能无需推测接下来会执行哪些指令。它可以将即将执行的代码从程序内存加载到预取指令缓存中,速度很快。

而“如果设置了分支”则意味着分支预测会推测并抓住机会执行哪些代码,如果猜错了,则必须从程序内存而不是缓存中加载代码,这速度要慢得多。

【讨论】:

    【解决方案2】:

    在这个简单的例子中,assembly output 完全一样:

    void f1()
    {
        int value = 1;
        while(value) {
            scanf("%d", &value);
        }
    }
    
    void f2()
    {
        int value = 1;
        while(1) {
            if(value == 0)
                break;
            scanf("%d", &value);
        }
    }
    

    因此它们具有相同的性能。

    如有疑问,请使用编译器资源管理器来比较汇编代码。或者使用分析器。

    【讨论】:

      【解决方案3】:

      你不能先验地说出速度。 C 的编译器将代码翻译成许多中间语言,并且在每次转换期间它都会更改代码表示形式。如今,编译器可以对代码进行大量更改。了解最终代码性能的唯一方法是检查输出程序集。通常,现在任何编译器都会将while(TRUE) {...} 转换为LOOP: ... goto LOOP,因为它可以证明TRUE 不为零。

      当使用内部函数比使用哨兵表示布尔值更快时,您的问题在最小编译或代码的简单解释的上下文中是有意义的。

      【讨论】:

      • 有一个更新澄清了这个问题,请检查一下
      • @Kaiyaha 很难说,因为您使用的翻译器会尝试证明有关代码的内容,以查看它可以对代码进行哪些更改。在您的代码中,翻译器可以将while (!done) ... 循环转换为无限循环while (TRUE) { body } ,如果它可以证明(condition) 始终为假。第一种情况也是如此。见researchgate.net/publication/…
      • 所以你的答案是,从编译器的角度来看,现在不可能说第二段和第三段代码是否比第一段慢,对吧?
      • @Kaiyaha 编译器实现来自“流分析”类en.wikipedia.org/wiki/Data-flow_analysisen.wikipedia.org/wiki/Control_flow_analysis 的算法。所以是的,根据编译器实现的算法以及给定的静态分析如何证明您的代码,翻译后的代码可能与初始代码有很大不同。
      • @Kaiyaha 在您给定的示例中,称为“恒定传播”en.wikipedia.org/wiki/Constant_folding 的算法可以将您的两个示例都简化为一个简单的 goto 循环。
      猜你喜欢
      • 1970-01-01
      • 2017-06-29
      • 1970-01-01
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2014-11-26
      • 2019-12-17
      • 1970-01-01
      相关资源
      最近更新 更多