下面2段代码基本来自《Scala By Example》一书
正常的写法:(scala写的,但逻辑与实现和传统的JAVA排序一致)
def sort(xs: Array[Int]){
def swap(i:Int, j:Int){
val t = xs(i); xs(i) = xs(j); xs(j) = t
}
def sort1(l: Int, r: Int){
val pivot = xs((l + r)/2)
var i = l; var j = r;
while (i <= j){
while (xs(i) < pivot) i += 1
while (xs(j) > pivot) j -= 1
if(i <= j){
swap(i, j)
i += 1
j -= 1
}
}
if(l < j) sort1(l, j)
if(j < r) sort1(i, r)
}
sort1(0, xs.length - 1)
}
Scala中的漂亮写法:
def quickSort(xs: Array[Int]): Array[Int] = {
if(xs.length <= 1) xs
else{
val pivot = xs(xs.length / 2)
Array.concat(
quickSort(xs filter (pivot >)),
xs filter (pivot ==),
quickSort(xs filter (pivot <))
)
}
}
单从视觉效果上看,第二种写法绝对是精妙绝伦,排除了传统JAVA实现中的i+=1,j+=1这种缺乏直观理解的逻辑,采用filter过滤合适数据进行迭代。
本来我就要被书上这种漂亮的写法诱惑了,大有往后就贴近这种风格来写的冲动,但忍不住测试了下效率让我大跌眼镜:
采用具有16个随机数的Array测试。
当用System.currentTimeMillis()计时:
时间1:0
时间2:17
第一种方法居然用毫秒都无法记录到时间?那就逼迫我们用nanoTime()来计时了:
时间1:11974
时间2:17514962
居然差了3个数量级= =
这就是漂亮代码的代价么。。。
大体上看来,第二种方式之所以慢应该是filter造成的,咱们可爱的filter每次都遍历集合,因此第二种方法并没有根据已排序的数据来减少后续的排序元素数量,每次都全部遍历自然效率比较低。