Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm Scala与Java性能_Algorithm_Scala_Sorting - Fatal编程技术网

Algorithm Scala与Java性能

Algorithm Scala与Java性能,algorithm,scala,sorting,Algorithm,Scala,Sorting,我遇到了Scala和Java性能之间的一个非常奇怪的差异。我在Java中实现了一个反转计数例程,然后将它逐行移植到Scala,因为所有惯用的Scala版本(使用List或Stream)要么非常慢,要么由于堆栈溢出/内存不足错误而崩溃。但是这个版本也很慢,而Java版本需要22毫秒来处理100000个整数的数组,Scala版本需要3秒钟。以下是Scala版本的相关代码: def mergeAndCountInversions(xs: Array[Int], aux: Array[Int], l

我遇到了Scala和Java性能之间的一个非常奇怪的差异。我在Java中实现了一个反转计数例程,然后将它逐行移植到Scala,因为所有惯用的Scala版本(使用
List
Stream
)要么非常慢,要么由于堆栈溢出/内存不足错误而崩溃。但是这个版本也很慢,而Java版本需要22毫秒来处理100000个整数的数组,Scala版本需要3秒钟。以下是Scala版本的相关代码:

  def mergeAndCountInversions(xs: Array[Int], aux: Array[Int], left: Int, right: Int) = {
    xs.copyToArray(aux)
    val m = left + (right - left) / 2

    var i = left
    var j = m + 1
    var inv: Long = 0

    for (k <- left to right) {
      if (i > m) {
        xs(k) = aux(j)
        j += 1
      } else if (j > right) {
        xs(k) = aux(i)
        i += 1
      } else if (aux(j) < aux(i)) {
        xs(k) = aux(j)
        j += 1
        inv += (m - i) + 1
      } else {
        xs(k) = aux(i)
        i += 1
      }
    }
    inv
  }
def mergeAndCountInversions(xs:Array[Int],aux:Array[Int],left:Int,right:Int)={
X.copyToArray(辅助)
val m=左+(右-左)/2
变量i=左
var j=m+1
var inv:Long=0
用于(k m){
xs(k)=辅助(j)
j+=1
}否则,如果(j>正确){
xs(k)=辅助(i)
i+=1
}如果(辅助(j)<辅助(i)){
xs(k)=辅助(j)
j+=1
库存+=(m-i)+1
}否则{
xs(k)=辅助(i)
i+=1
}
}
投资部
}
关于如何提高这套动作的表现有什么想法吗


UPD:Scala版本性能差完全是我的错。第一条语句不必要地将整个数组复制到辅助数组。当改变为只复制所需的部分时,性能与java应该是一样的。

很可能是因为理解。它被剥去了糖衣

Range(left, right).foreach { k =>
  // code...
}
为了使其与Java解决方案具有可比性,必须用while循环替换它

var k = left

while (k <= right) {
  // code...

  k += 1
}
var k=left

虽然(阿纳尔席)java(虽然我还没有足够的Scala WIZ来写一个答案,但是考虑到Scala中的数组索引在数组对象上调用<代码>应用程序/Cuff>方法-与使用方括号的数组访问语法时,在引擎盖下执行的指针算术不完全相同。首先,用以测量性能。预热后使用ce。我猜在内联后您将获得相同的性能。您也可以在编译时使用以下命令来强制内联:
for(k@senia)我已经用使用的基准例程更新了这个问题。我发现,将scala的理解重建为尾部递归算法通常具有性能优势(如果你能做到的话)。编译器似乎在优化这些方面做得更好。啊,synapse,我刚刚在CodeReview上查看了你最初的Scala实现;)我想,你还没有完全理解尾部递归/优化。我已经给出了一个例子。是的,我认为这可能是原因,但性能与
相同,而
我不理解的是为什么Scala编译器没有找到优化
范围的方法(…).foreach
构造成与Java for循环生成的相同的底层字节码…@ErikAllik for在scala中比通常的Java循环构造做了更多的工作为了优化最简单的情况,我用for和while测试了它,速度快得多。@drexin这真的很奇怪。你的环境是什么?我在Mac OS X上使用Scala 2.10.2和JDK 1.6。