Performance Scala if-else效率改进

Performance Scala if-else效率改进,performance,scala,if-statement,Performance,Scala,If Statement,以下代码段在应用程序中被调用数百万次 val res = myArray.map { case (expr1,expr2) => val nan1 = expr1.isNaN val nan2 = expr2.isNaN if (nan1 && nan2) 0.0 else if (nan1 && !nan2) expr2 else if (!nan1 && nan2) expr1 else expr1-expr2

以下代码段在应用程序中被调用数百万次

val res = myArray.map { case (expr1,expr2) =>
  val nan1 = expr1.isNaN
  val nan2 = expr2.isNaN

  if (nan1 && nan2) 0.0
  else if (nan1  && !nan2) expr2
  else if (!nan1 && nan2) expr1
  else expr1-expr2
}
其中
myArray
通常包含100到1000对


有没有办法让它(甚至)更快呢?

你可以省去
&&!nan2
!nan1&
,因为您已经确定不是两个都是真的(上面测试过)。但是,优化器可能也会注意到这一点,并删除代码,因此我怀疑它会影响性能。

< P>如果这是性能瓶颈,请考虑在一对数组上使用一对各自的原始类型数组(<代码>双< /代码>),并编写一个好的旧代码> 循环,正如@wingedsubmariner所建议的那样

为了回答您最初的问题,假设NAN很少,您可以通过重新排列if ELSE来获得边际加速,以便首先确定最常见的情况,尤其是因为分支预测:

if (!nan1 && !nan2) expr1-expr2
else if (nan1) if (!nan2) expr2 else 0.0
else expr1
或者可能:

if (!nan1)
  if (!nan2) expr1-expr2 else expr1
else 
  if (!nan2) expr2 else 0.0

但您可能必须将此代码片段简化为一个微基准,并使用类似的方法对其进行测量,以注意差异。

我认为主要的性能损失不是if/else语句,而是使用map和pattern matching(假设expr*不重)来构建om nom所说的,如果您使用
while
循环而不是使用
map
来重写它,您还可以将
myArray
分解为两个单独的数组,而不是使用包含元组的数组。这就消除了通过元组间接的水平。也许尝试<代码> MyARay.PAR.MAP {…} /代码> @ WangDeDeBaseNER,请考虑此评论作为上投票的答案:)多谢