【问题标题】:Which if statement would execute faster?哪个 if 语句执行得更快?
【发布时间】:2014-09-23 10:22:11
【问题描述】:

假设我们有一个对象,我们需要验证以下内容 -

  • Object->文本长度大于0
  • Object->dummy 不为空
  • Objecct->dummy2 存在于另一个对象中

if 语句有两种可能性:

if(greaterThan(Object->text, 0) && 
   exists(Objet->dummy) && 
   inObject(Object->dummy2, Objet2))

第二种情况:

if(!greaterThan(Object->text, 0) || 
       !exists(Objet->dummy) || 
       !inObject(Object->dummy2, Objet2)) {
  NOP  
 } else {
   //Do something;
}

哪个会更快?提前致谢。

【问题讨论】:

  • 你为什么在乎?您是否注意到那里的性能受到影响?我真的怀疑。 “过早的优化是万恶之源”……只要写出最容易阅读的内容。
  • generalu 第一个,因为您的操作较少,第一个的最坏情况是 2 AND,而第二个最坏的情况是 2 OR 和 3 NEGATION
  • 你为什么关心他为什么关心?通过重复疲惫的“过早优化......”引用,您隐含地假设 OP 实际上是在过早地优化它,甚至他正在优化它。有时你只是想知道为什么,即使没有实际的好处。事实上,这个问题被标记为“理论”......

标签: performance algorithm theory


【解决方案1】:

一般来说,这两种形式是等价的,一个体面的编译器可能会将它们编译成相同的最终程序集。当然,您应该检查您的特定编译器。您可以在这里查看一些编译器的汇编输出来解决您的问题:

http://goo.gl/FeSmEa

例如 gcc 4.9 的输出:

void function1() {
  if (greaterThan() &&  exists() && inObject()) {
    result = 42;
  }
}

给予:

function1():
    sub rsp, 8
    call    greaterThan()
    test    eax, eax
    jne .L13
.L1:
    add rsp, 8
    ret
.L13:
    call    exists()
    test    eax, eax
    je  .L1
    call    inObject()
    test    eax, eax
    je  .L1
    mov DWORD PTR result[rip], 42
    jmp .L1

另外一个变种:

void function2() {
  if (!greaterThan() ||  !exists() || !inObject()) {
    // NOP
  } else {
    result = 42;
  }
}

导致相同的装配:

function2():
    sub rsp, 8
    call    greaterThan()
    test    eax, eax
    jne .L28
.L14:
    add rsp, 8
    ret
.L28:
    call    exists()
    test    eax, eax
    je  .L14
    call    inObject()
    test    eax, eax
    je  .L14
    mov DWORD PTR result[rip], 42
    jmp .L14

在所有情况下,编译器都会为这两个选项生成相同的程序集(我通过删除一些参数稍微简化了它,但这应该无关紧要)。

【讨论】:

  • 是的,我完全希望所有明智的编译器都能以相同的方式编译它们。
  • 哇,这很有趣。我问是因为我想阻止 if 调用其他函数,谢谢
  • 您无需查看程序集即可确定 - 该语言定义了短程布尔运算符,因此根据定义,当布尔表达式的值已设置时,您将不会调用函数.就该行为而言,您的两个表达式是等效的。在这种情况下,重要的是您输入表达式的顺序。您想要一个更有可能首先“短路”其余表达式的顺序。例如,对于A && B,您希望将AB 中最有可能为假的一个放在第一位。
猜你喜欢
  • 1970-01-01
  • 2017-08-29
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 2015-10-26
  • 2011-03-08
相关资源
最近更新 更多