表现:if(i == 0)与if(!i)

时间:2014-11-23 20:28:15

标签: c++ performance optimization

我正在编写(或者至少尝试编写)一些高性能的C ++代码。我遇到了一个需要进行大量整数比较的部分,即检查结果是否等于零。

哪个效率更高?也就是说,这需要更少的处理器指令?

if (i == 0) {
    // do stuff
}

if (!i) {
    // do stuff
}

我在x86-64架构上运行它,如果这有任何区别的话。

3 个答案:

答案 0 :(得分:8)

让我们用gcc:

来看看这段代码的汇编(没有优化)
void foo(int& i)
{
  if(!i)
    i++;
}

void bar(int& i)
{
   if(i == 0)
     i++;
}

int main()
{
  int i = 0;
  foo(i);
  bar(i);
}

foo(int&):                               # @foo(int&)
    movq    %rdi, -8(%rsp)
    movq    -8(%rsp), %rdi
    cmpl    $0, (%rdi)
    jne .LBB0_2
    movq    -8(%rsp), %rax
    movl    (%rax), %ecx
    addl    $1, %ecx
    movl    %ecx, (%rax)
.LBB0_2:
    ret

bar(int&):                               # @bar(int&)
    movq    %rdi, -8(%rsp)
    movq    -8(%rsp), %rdi
    cmpl    $0, (%rdi)
    jne .LBB1_2
    movq    -8(%rsp), %rax
    movl    (%rax), %ecx
    addl    $1, %ecx
    movl    %ecx, (%rax)
.LBB1_2:
    ret

main:                                   # @main
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    leaq    -8(%rbp), %rdi
    movl    $0, -4(%rbp)
    movl    $0, -8(%rbp)
    callq   foo(int&)
    leaq    -8(%rbp), %rdi
    callq   bar(int&)
    movl    -4(%rbp), %eax
    addq    $16, %rsp
    popq    %rbp
    ret

底线:

生成的程序集完全相同(即使未启用优化),因此无关紧要:选择更清晰,最易读的语法,在您的情况下可能是if( i == 0)

在C ++中,你几乎不需要关心这样的微优化,编译器/优化器在这个游戏中非常擅长:相信它们。如果不这样做,并且遇到性能瓶颈,请查看/查看特定平台的程序集。

注意:

  • 您可以使用godbolt.org生成此类程序集,这是一个非常方便的工具。
  • 你也可以在gcc上使用-S选项来生成程序集(其他编译器有类似的选项)

答案 1 :(得分:1)

除非你有一个疯狂的编译器,否则它们应该编译相同。话虽如此,为了让未来的人看到您的代码的合理性,如果i == 0是数字类型,则仅使用i;如果!ii,则只使用bool } type。

答案 2 :(得分:0)

没有更好的已知编译器的编译器会将这些编译成任何非常不同的东西,以至于在执行手动优化之前执行所有人必须执行的操作时会很重要:测量。