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

时间:2014-12-07 01:14:04

标签: performance algorithm language-agnostic max double-precision

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

我见过解决方案,such as

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

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

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

3 个答案:

答案 0 :(得分:2)

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

这为任何大小的列表带来了好处......对于非常大的列表,使用多线程也是有意义的。

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

编辑:这是我的尝试答案,但请查看@BenVoigt建议更好地优化表达的方法


  • 您需要至少遍历整个列表
  • 因此,如果有的话,if (d>max) max=d会找到更有效的表达方式。

假设我们需要一般情况,其中列表未排序(如果我们保持排序,我们只需在评论中选择最后一项作为@IgnacioVazquez点),并研究一下关于分支预测Why is it faster to process a sorted array than an unsorted array?,请参阅第4个答案),看起来像

 if (d>max) max=d;

可以更有效地重写为

 max=d>max?d:max; 

原因是,第一个语句通常被翻译成分支虽然它完全依赖于编译器和语言,但至少在C和C ++中,甚至在基于VM的语言如Java发生),而第二种语言则转换为条件移动

如果预测出错(执行流水线必须重置),现代处理器在分支中会有很大的损失,而条件移动是一种不会影响流水线的原子操作。

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

请参阅链接的问题,以便与基准测试一起讨论所有这些问题。