Swift的sort()基准,与存储桶排序相比,它是timsort:
项目数| Swift的sort()|桶分类|区别:
计算机:iMac Pro(2017),3.2 GHz Intel XeonW。这些值适用于硬编码的self.max()
。提供的代码工作时间更长。
为什么编程语言(包括Swift)不使用更快的存储桶排序?
import Foundation
extension Array where Element == Int {
mutating func sort() {
guard count > 0 else {
return
}
var count = [Element:Int]()
for item in self {
if count[item] != nil {
count[item] = count[item]! + 1
} else {
count[item] = 1
}
}
let n = self.max()!
self = []
for value in 0..<n {
if let count = count[value] {
for _ in 0..<count {
self.append(value)
}
}
}
}
}
func sort(n: Int) {
var array = [Int]()
for _ in 0..<n {
let newItem = Int.random(in: 0..<n)
array.append(newItem)
}
let start = CFAbsoluteTimeGetCurrent()
array.sort()
let end = CFAbsoluteTimeGetCurrent()
print("Time: \(end - start)")
}
sort(n: 1000000)
P.S。内存消耗几乎相同。
以下代码适用于任何类型,但速度较慢。但是它仍然比Swift中的sort()方法的当前实现好一点。因此,该主题仅适用于对整数排序。
项目数| Swift的sort()|桶分类|区别:
计算机:iMac Pro(2017),3.2 GHz Intel Xeon W
import Foundation
extension Array where Element: Comparable & Hashable {
mutating func sort() {
var count = [Element:Int]()
for item in self {
if count[item] != nil {
count[item] = count[item]! + 1
} else {
count[item] = 1
}
}
self = []
let keys = count.keys.sorted()
for value in keys {
if let count = count[value] {
for _ in 0..<count {
self.append(value)
}
}
}
}
}
func sort(n: Int) {
var array = [Int]()
for _ in 0..<n {
let newItem = Int.random(in: 0..<n)
array.append(newItem)
}
let start = CFAbsoluteTimeGetCurrent()
array.sort()
let end = CFAbsoluteTimeGetCurrent()
print("Time: \(end - start)")
}
sort(n: 1000000)
答案 0 :(得分:2)
周围没有“最快的排序”,它取决于数据。
例如,对于已被排序最快的数据,则为气泡排序:您什么也不动,仅在读取输入后便知道已完成。即使对于几乎已排序的数据,在某些情况下,气泡排序算法的变化(足够令人惊讶)也是非常合理的选择(例如,基于链接列表的扫描线渲染器,其中许多x值会从一条扫描线中进行少量更新)到下一个)。
在某些情况下,桶排序是一个很好的选择,但前提是密钥很小,或者可以将其分成不太多的小块(并非总是如此)。
快速排序和变体使用随机来避免最坏的情况,并且仅在键之间使用小于比(总是可用)。如果对数据了解不多,并且适合快速随机存取存储器,那么这是一个很好的默认选择。
根据情况,您可能想要最小化比较,或者可能想要最小化交换。不是同一回事。
如果数据太大而无法快速存储,并且整个集合上的随机访问都存在问题,那么合并排序可能是一个不错的选择。
...
换句话说,这取决于:-)
根据我的经验,仅对小整数数组进行排序的测试用例不是很常见。
答案 1 :(得分:-1)
正确的答案是:
通用代码(请参阅“更新”部分)具有几乎相同的性能。