性能主题

scala和java性能基准测试

  我们要选择一个性能测试样本:快速排序算法这个很简单的算法。提供Scala和Java的实现,排序100000元素100倍,看看每个需要多久完成排序。开始用Java:

public static void quickSort(int[] array, int left, int right) {
    if (right <= left) {
        return;
    }
    int pivot = array[right];
    int p = left;
    int i = left;
    while (i < right) {
        if (array[i] < pivot) {
            if (p != i) {
                int tmp = array[p];
                array[p] = array[i];
                array[i] = tmp;
            }
            p += 1;
        }
        i += 1;
    }
    array[right] = array[p];
    array[p] = pivot;
    quickSort(array, left, p - 1);
    quickSort(array, p + 1, right);
}

Scala代码:

def sortArray(array: Array[Int], left: Int, right: Int) {
  if (right <= left) {
    return
  }
  val pivot = array(right)
  var p = left
  var i = left
  while (i < right) {
    if (array(i) < pivot) {
      if (p != i) {
        val tmp = array(p)
        array(p) = array(i)
        array(i) = tmp
      }
      p += 1
    }
    i += 1
  }
  array(right) = array(p)
  array(p) = pivot
  sortArray(array, left, p - 1)
  sortArray(array, p + 1, right)
}

性能对比:

看来Scala比Java快近20%.

为什么Scala是比Java快? Scala和Java都在JVM上运行。他们的源代码都编译成字节码,从JVM角度来看,它不知道是Scala或是Java ,它只是所有的JVM字节码。如果我们看一下Scala和Java编译的字节码,我们会发现一个关键的事情,在Java代码中,有两个递归调用快速排序例程,而在Scala中,只有一个。这是为什么?

注意到Scala的代码写法不是我们平常风格,这里是一个实现快速排序惯用idiomatic的Scala风格:

def sortList(list: List[Int]): List[Int] = list match {
case Nil => Nil
case head :: tail => sortList(tail.filter(_ < head)) ::: head :: sortList(tail.filter(_ >= head))
}

那么这个代码如何?

黄色部分是惯用的idiomatic Scala,性能落后很多。

Scala的目的是建立一个"可扩展Scalable的语言"。正如我们已经看到,这种可扩展性不适合做JVM内微基准测试,Scala适合在JVM之间扩展。

扩展性主题