斯卡拉 - 不变性表演

fed*_*gon 3 scala

注意:尽管我将使用Akka教程代码作为测试用例,但我的问题是关于Scala不变性性能,以及如何调整JVM因此

我正在接近Akka,我正在尝试其教程代码Akka开始 ; 我将源代码从教程粘贴到我自己的项目并运行它,获得此输出:

Calculation time:       660 milliseconds
Run Code Online (Sandbox Code Playgroud)

在此之后,我尝试了一点代码,重写了这个函数

def calculatePiFor(start: Int, nrOfElements: Int): Double = {
  var acc = 0.0
  for (i <- start until (start + nrOfElements))
    acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1)
  acc
}
Run Code Online (Sandbox Code Playgroud)

不使用var累加器,就像这样

def calculatePiFor(start: Int, nrOfElements: Int): Double = {
  val range = start until (start + nrOfElements)
  val computation = range.map(i => 4.0 * (1 - (i % 2) * 2) / (2 * i + 1))
  computation.sum
}
Run Code Online (Sandbox Code Playgroud)

好吧,它有效,但表现有点堕落

Calculation time:       1737 milliseconds
Run Code Online (Sandbox Code Playgroud)

我的问题是:我的功能有什么重大错误,或者毫无疑问会导致这些表现吗?如果没有,有人能指出一个好的规则来调整JVM以改善这些性能吗?

我在Scala 2.9上运行我的代码,使用sbt 0.12.0及其默认的java选项(捆绑在sbt.bat中):

_JAVA_OPTS=-Xmx512M -XX:MaxPermSize=256m -XX:ReservedCodeCacheSize=128m
Run Code Online (Sandbox Code Playgroud)

提前致谢

par*_*tic 7

通过使用将获得更好的表现foldLeft,将在一次通过中计算总和作为您显示的命令性示例:

val computation = range.foldLeft(0.0){
  case (sum,i) => sum + 4.0 * (1 - (i % 2) * 2) / (2 * i + 1))
}
Run Code Online (Sandbox Code Playgroud)

但是,它可能仍然比它的命令对手慢.如果它确实是您的应用程序的瓶颈,您应该使用最快的版本(带有while循环的命令式版本).它对Actors是安全的,因为可变状态将被完全隔离.

在所有其他情况下,最好使用凌乱的代码丢失几个百分比的性能(在整个应用程序中测量).