【发布时间】:2017-04-01 04:44:30
【问题描述】:
我正在比较用 scala 语言编写的两个代码。
package chapter01
object QuickSortScalaTime {
def sortFunctional(xs: Array[Int]): Array[Int] = {
if (xs.length <= 1) xs
else {
val pivot = xs(xs.length / 2)
Array.concat(sortFunctional(xs filter (pivot >)), xs filter (pivot ==), sortFunctional(xs filter (pivot <)))
}
}
def sortTraditionl(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)
}
def main(args: Array[String]): Unit = {
val arr = Array.fill(100000) { scala.util.Random.nextInt(100000 - 1) }
var t1 = System.currentTimeMillis
sortFunctional(arr)
var t2 = System.currentTimeMillis
println("Functional style : " + (t2-t1))
t1 = System.currentTimeMillis
sortTraditionl(arr)
t2 = System.currentTimeMillis
println("Traditional style : " + (t2-t1))
}
}
第一个块是用函数式编写的,第二个块是传统的快速排序。顺便说一下,这些例子来自奥德斯基的书。
传统和实用之间存在巨大差异。
Functional style : 450
Traditional style : 30
我只是想知道是什么导致了这种差异。我不深入了解 scala,但我最初的猜测是传统的不使用突变和任何闭包。我们可以做些什么来提高函数式样式的性能?
【问题讨论】:
-
在 scala 中完全可以接受在本地使用可变状态来使事情变得更快。 Martin Odersky 本人在 2013 年 scala 日的主题演讲中提出了这一点 youtube.com/watch?v=kkTFx3-duc8 。因此,在现实世界中,您的 sortFunctional 方法将创建要排序的数组的副本,并在内部使用普通的就地快速排序。只要可变状态仍然局限于本地方法,它是无害的。
-
请注意,您的测试不会强制 Java 运行时首先编译代码,因此对这些时间几乎无能为力。不过,我希望就地排序会快得多,而且由于对大型数据集进行排序非常耗时,因此它通常是优化的目标。当然,它已经在 std 库中为您完成了:scala-lang.org/api/current/index.html#scala.util.Sorting$ 有关性能的更多信息,请参阅nicholassterling.wordpress.com/2012/11/16/scala-performance
标签: scala