Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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
Performance 按性能排序的Scala集合、sortWith和sortBy_Performance_List_Scala_Sorting_Collections - Fatal编程技术网

Performance 按性能排序的Scala集合、sortWith和sortBy

Performance 按性能排序的Scala集合、sortWith和sortBy,performance,list,scala,sorting,collections,Performance,List,Scala,Sorting,Collections,Scala在标准库中包含了几种对列表进行排序的方法,例如,要对列表进行排序,可以使用: list.sorted list.sortWith(_<_) list.sortBy(x=>x) list.sorted list.sortWith(x) 虽然这些可能是对列表进行排序的最简单方法,但我发现对于较大的列表,它们有显著的性能缺陷 例如,要对一百万个整数进行排序,排序平均需要500毫秒,而sortWith和sortBy大约需要700毫秒。这与scala.util.Sorting.q

Scala在标准库中包含了几种对列表进行排序的方法,例如,要对列表进行排序,可以使用:

list.sorted
list.sortWith(_<_)
list.sortBy(x=>x)
list.sorted
list.sortWith(x)
虽然这些可能是对列表进行排序的最简单方法,但我发现对于较大的列表,它们有显著的性能缺陷

例如,要对一百万个整数进行排序,排序平均需要500毫秒,而sortWith和sortBy大约需要700毫秒。这与scala.util.Sorting.quickSort(大约需要120毫秒)和java.util.Arrays.sort(大约需要100毫秒)相比。对于较大的列表,随着我们进一步扩展,可以观察到这种多因素差异。模式如下图所示


绩效滞后的原因是什么?为什么标准方法没有使用更有效的算法/实现?

注意,这些线是如何具有相同的斜率,但彼此偏移的?对于对数标度,我们看到的是常数因子差
sorted
和朋友支付将
列表
转换为
数组
、排序(实际上使用
java.util.Arrays.sort
)和转换回
列表
的费用
scala.util.Sorting.quickSort
java.util.Arrays.sort
直接对数组进行操作。quicksort的
n log n
性能中的
log n
因子在很大程度上是不相关的,因此,对于创建数组和结果列表所需的线性时间,我们最终得到一个常数因子差。性能差五倍可能看起来很糟糕,但请记住
列表
中的每个元素都有一个cons单元格,这使得在创建
数组
时需要大量随机访问,然后创建新的
列表
需要花费时间分配内存,而且很可能,一两个垃圾收集周期

对于原语列表,情况更糟<代码>列表是通用的,因此任何原语都必须装箱,这增加了另一层间接寻址。不幸的是,创建的
数组
也包含装箱的值。实际上,当您确实想对
数组[Int]
进行排序时,您最终会对
数组[java.lang.Integer]
进行排序


总而言之:排序算法是相同的,但有充分的理由说明可变数组优于不可变单链表。

除了wingedsubmariner解释的内容外,请注意快速排序不是一种稳定的排序。简单排序适合于少量元素,是一种稳定的排序,它不需要原始数据,可以处理所有集合类型。快速排序是一种非稳定的数组就地排序,为了获得更好的性能,如果您有很多项,那么值得努力使用。您不是每次都看到一个数量级的差异,而不是一个常量吗difference@monkjack-一个恒定的乘法因子(例如10倍)。你的答案有道理,但我尝试在quickSort和java sort的时间度量中包含toArray/toList转换,对于一百万个记录,我只看到20毫秒的增加,而500毫秒的差异仍然存在。你对此有什么解释吗?@deepkimo是的,请看我的新编辑。创建的数组包含装箱的值,因此排序速度要慢得多。@deepkimo它使用
排序(T[]a,Comparator)