繁体   English   中英

查找最大双精度值的最有效算法

[英]Most effective Algorithm to find maximum of double-precision values

在一组变量中找到最大值的最有效方法是什么?

我看到了解决方案, 例如

private double findMax(double... vals) {
double max = Double.NEGATIVE_INFINITY;

for (double d : vals) {
   if (d > max) max = d;
}
    return max;
}

但是,最有效的算法是什么?

如果列表未排序,则无法将复杂度降低到O(n)以下...但是您可以将常数因子提高很多。 使用SIMD。 例如,在SSE中,您将使用MAXSS指令在单个周期内执行4位比较+选择操作。 稍微展开循环以降低循环控制逻辑的成本。 然后在循环之外,从SSE寄存器中捕获的四个值中找出最大值。

这对于任何大小的列表都有好处...对于真正的大列表,使用多线程也是有意义的。

假设列表中没有按任何特定顺序排列的元素,那么您在问题中提到的算法是最佳的。 它必须查看每个元素一次,因此花费的时间与列表的大小O(n)成正比。

没有找到上限小于O(n)的最大值的算法。

证明:假设有一个矛盾,有一种算法可以在不到O(n)时间内找到列表的最大值。 然后必须至少有一个它不检查的元素。 如果算法选择该元素为最大值,则对手可能会为该元素选择一个值,使其小于被检查的元素之一。 如果算法选择任何其他元素作为最大值,则对手可能会为该元素选择一个值,使其大于其他元素。 无论哪种情况,该算法都无法找到最大值。

编辑:这是我的尝试答案,但是请看一下@BenVoigt提出了一种优化表达式的更好方法的评论


  • 您需要至少遍历整个列表一次
  • 因此,对于if (d>max) max=d (如果有if (d>max) max=d ,找到一个更有效的表达式是一个问题。

假设我们需要列表未排序的一般情况(如果我们将其保持排序,那么我们将在评论中将最后一项选择为@IgnacioVazquez点),然后对分支预测进行一些研究( 为什么处理排序的索引更快?数组比未排序的数组? ,请参阅第4个答案),看起来像

 if (d>max) max=d;

可以更有效地重写为

 max=d>max?d:max; 

原因是,第一个语句通常翻译为分支尽管它完全依赖于编译器和语言,但是至少在C和C ++中,甚至在Java等基于VM的语言中也会发生 ),而第二个语句则翻译为有条件的行动

如果预测出错(必须重置执行管道),则现代处理器在分支机构中将遭受重大损失,而条件移动是原子操作,不会影响管道。

列表中元素的随机性质(一个概率可以相等于大于或小于当前最大值)将导致许多分支预测出错。

请参考链接的问题,对所有这些以及基准进行很好的讨论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM