java timsort_Java 7是否对方法Arrays.Sort使用Tim Sort?

6cb03e0c1c17139642203473c8badd74.png

慕容森

是! ...也没有摘要在撰写本文时(2016年),在当前的Open JDK 0实现中,Tim Sort通常用于对对象(即Arrays.sort(Object[])和朋友)的数组进行排序-但是对于原始数组(Arrays.sort方法的其余部分),可以使用多种其他方法。对于基元,试探法在各种排序方法中进行选择,例如快速排序,合并排序,计数排序3。取决于要排序的数据。这些决策中的大多数决策都是基于要排序的数组的类型和大小而预先简单地做出的,但是对于int和long元素而言,决策实际上是根据测得的数组排序进行自适应的。因此,在很多情况下,您都需要在适应/内省(TimSort或类似的合并排序)的基础上进行适应/内省(启发式算法选择算法)!细节Tim Sort用于大多数对象,例如Arrays.sort(Object[] a),除非用户通过将system属性设置java.util.Arrays.useLegacyMergeSort为true来专门请求旧版行为。对于基元,情况更加复杂。至少从JDK 8(版本1.8.0_111)开始,根据要排序的数组的大小,原始类型和数组的已测量“排序度”,使用了各种启发式方法。概述如下:对于字节1以外的所有基本类型,少于47个元素的数组仅使用插入排序进行排序(请参阅参考资料DualPivotQuicksort.INSERTION_SORT_THRESHOLD)。该阈值还排序中出现时合并子阵列时使用或快速排序的使用和所述子阵列的大小低于该阈值。因此,某种形式的插入排序将用于所有排序,对于小数组,这是唯一使用的算法。对于原始类型byte,short并且char,一个计数排序用于稍大阵列。这是一种简单的排序,需要花费O(n + range)时间,其中range为字节(256)或short / char(65536)值的总数。排序涉及分配range值的基础数组,因此仅在要排序的元素数量占总范围的很大一部分时才使用它。特别是,它用于大于29个元素的字节数组(即〜11%的范围)和大于3200个元素的short / char数组(占范围的5%)。对于字节数组,始终使用以上两种方法之一。对于int和long上述插入排序阈值和用于阵列short/ char可使用上述两种插入排序阈值且低于所述计数排序阈值阵列,两种算法之一:双枢轴快速排序,或合并排序。哪一个被使用取决于阵列的有序性的量度:输入被分成运行升序或降序元件。如果此类运行的数量大于66,则该数组被认为大部分未排序,并使用双轴快速排序进行排序。否则,该数组被认为是最有序的,并使用mergesort(使用已经枚举的运行作为起点)。尽管存在一些差异,但找到运行然后使用mergesort对它们进行排序的想法实际上与TimSort非常相似。因此,至少对于某些参数,JDK使用的是运行感知的合并排序,但是对于许多其他参数组合,JDK使用的是不同的算法,总共至少使用5种不同的算法!基本原理Object[]vs原语不同排序行为背后的原因可能至少有两个方面:1)排序Object[]必须稳定:排序相同的对象将以与输入相同的顺序出现。对于基元数组,不存在这样的概念:基元完全由它们的值定义,因此稳定和不稳定排序之间没有区别。这允许原始排序免除对稳定算法的需求,而有利于速度。2)Object[]涉及该Object.compare()方法的各种需求,可能是任意复杂和昂贵的。即使该compare()方法很简单,除非整个内联方法都可以内联2,否则通常会存在方法调用开销。因此Object[],即使以一些额外的算法复杂性为代价,通常也会偏向于使总比较最小化。另一方面,原始数组的排序只是直接比较原始值,这些原始值通常需要一个或两个周期。在这种情况下,应考虑比较成本和周围算法,对算法进行优化,因为二者的大小可能相同。0至少对于Java 7和Java 9之间的版本,它当然也包括基于Open JDK的Oracle JDK。这是可能的是,其他实现使用类似的方法,但我没有检查。1对于字节数组,插入排序阈值实际上是29个元素,因为这是使用计数排序的下限。2这似乎不太可能,因为它很大。3计数排序只是用于与的16位或更小范围相对有限值:byte,short或char。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值