有效地找到最小值和最大值

Posted

技术标签:

【中文标题】有效地找到最小值和最大值【英文标题】:Finding minimum and maximum efficiently 【发布时间】:2014-01-09 09:56:14 【问题描述】:

我有两个整数参数ab。还有两个整数变量maxmin。 我想将ab 的最大值分配给max,并将两者中的最小值分配给min。 我需要做这个操作数百万次,所以我想优化它。我目前正在做以下事情:

min = a < b ? a : b;
max = a > b ? a : b;

问题在于它需要两个 if 语句。我想知道是否有更好的方法来做到这一点。

【问题讨论】:

用什么语言?有些语言允许你做并行作业。 你可以使用 SSE 内在函数吗? 是的,我想,任何适用于 VS2012 的东西我都可以使用。 a 和 b 是从哪里来的? 它们是随机生成的。 【参考方案1】:
std::tie(min, max) = std::minmax(a, b);

【讨论】:

【参考方案2】:
if (a < b)

    min = a; max = b;

else

    min = b; max = a;

【讨论】:

是的,运行时间要少得多,谢谢! @BenjyKessler 你启用编译器优化了吗? 我使用的是 VS 2012,优化设置为最大化速度。【参考方案3】:

您可能过早地进行了优化。看看编译器是怎么做的。

对于只有一个条件的版本,这很简单:-

if (a < b)

  min = a;
  max = b;

else

  min = b;
  max = a;

【讨论】:

【参考方案4】:

或者你可能想使用一些数学:

int absdiff = abs (a-b);
int sum = a+b;
max = (sum+absdiff)/2;
min = (sum-absdiff)/2;

您可以相信编译器会根据基本类型优化所有内容,您可以摆脱分支并获得恒定的执行时间(不依赖于预测器)。

编辑:

英特尔处理器上的示例 abs 整数函数:

cdq 
xor eax, edx 
sub eax, edx 

【讨论】:

abs() 通常是使用条件实现的,因此您仍然有一个分支。 int _RTLENTRYF _EXPFUNC abs(int i) return (i &gt;= 0 ? i : -i); 有些输入不起作用,例如a = 1140851080; b = -158544698 当然。我们在这里谈论优化,否则您可以简单地采用a &lt; b ? a : b 方式。最大值必须允许几个 MSB,但谁说这应该在完整的 32 位规模上工作? 好吧,只要我们都知道这些限制 :) @harold 毕竟,单纯的整数减法已经是一个危险的陷阱;)【参考方案5】:
 min=a;max=b;
 if(a>b) 
   max=a;
   min=b;
  //Here you don't even need an else statement, i don't know how much time does else take but if it does then you have saved it.

【讨论】:

以上是关于有效地找到最小值和最大值的主要内容,如果未能解决你的问题,请参考以下文章

在数组中查找最小值和最大值

查找堆栈中的最大值和最小值

优雅地同时计算数字数组的最小值和最大值

使用 NumPy 从矩阵中获取最小/最大 n 值和索引的有效方法

如何在二叉树中找到最小值和最大值

如何在文件处理中从文本文件中找到每一行的最小值和最大值?