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

Mar*_*ean -3 c++ optimization performance

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

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

if (i == 0) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

要么

if (!i) {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

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

qua*_*dev 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);
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

底线:

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

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

注意:

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