【问题标题】:Is there a difference between the `if else` and the `if-else if-else`?`if else` 和 `if-else if-else` 之间有区别吗?
【发布时间】:2012-04-25 15:42:25
【问题描述】:

Binary SearchWikiPedia 文章中有一个名为Deferred detection of equality 的部分,它提供了一个有点“优化”的二分搜索版本,如下所示:

int binary_search(int A[], int key, int imin, int imax)  
{  
  while (imax > imin)  
  {  
    int imid = (imin + imax) / 2;  
    if (A[imid] < key)  
      imin = imid + 1;  
    else  
      imax = imid;  
  }  
  if((imax == imin) && (A[imin] == key))  
    return imin;  
  else  
    return KEY_NOT_FOUND;  
}  

据称这是一个比传统教科书二进制搜索更好的版本,因为.... algorithm uses only one conditional branch per iteration
这是真的?我的意思是if 指令在汇编中被翻译成CMPBranch 指令,所以我想不出if-elseif-else if-else 更好
我应该在高级语言中考虑到这种差异吗?我管理“延迟”版本的代码似乎更严格,但是您如何形成 if-else 语句有优化或惩罚吗?

【问题讨论】:

  • 我猜你的消息来源是在谈论汇编而不是 Java,在这种情况下我认为它不适用。另外,我敢打赌,它没有考虑到现代代码优化。
  • 另外,我希望这是一个学术问题,因为如果您根据这种性能评估做出编程决策,那么它就是过早优化的定义。
  • 你没有展示其他选择,所以不可能知道你在说什么。
  • @Gray:没有教科书,维基百科。这不是一个编程决定。只是在我的业余时间回顾一下基础
  • @HotLicks:另一种选择是众所周知的if(a[mid] == key){}else if (a[mid] &lt; key) else{}

标签: java algorithm optimization assembly compilation


【解决方案1】:

关键概念是它使用较少的条件每次迭代。也就是说,相等性检查已移到 while 循环之外,因此它只运行一次,而在基本版本中,每次都需要检查。

也就是说,我不确定在使用优化形式时是否真的会有可测量的差异。例如,考虑一下:

  1. 如果您要比较的只是两个整数,那么编译器可以检测到它可以只计算一次比较结果,然后同样评估要采用哪个分支。
  2. 二分搜索是 O(logN),因此即使要搜索的元素数量很大,所进行的迭代次数实际上也会非常少。您是否会看到有什么不同,这是有争议的。
  3. 现代 CPU 功能的实现,例如推测执行和分支预测(尤其是在像二进制搜索这样的“好”算法中)很可能比这种优化产生更明显的效果(尽管我不同意)。

注意事项:

¹实际上是另一个条件,当相等比较移出时不需要检查,但在概念上没有区别。

【讨论】:

  • +1。这是有道理的。但是文章的措辞似乎暗示了一些不同的东西(至少在我的理解上)
  • 在引用的 Wikipedia 文章中,在 OP 所描述的版本之上有一个版本,它执行 if(>)elseif(
  • 比较是现代 CPU 上最便宜的指令之一,最昂贵的部分是分支错误预测。因此,如果第二个版本无助于节省这些时间,则节省的周期数可以忽略不计。
  • @spinning_plate:理论上它每次都需要计算elseif(&lt;)。这就是我的注释 #1 所说的。
  • @Voo:我同意这一点,但我们可能不是在谈论整数,因此比较可能会产生任意成本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多