我在swift中使用默认排序算法。 但是对于10000(10k)的记录,在ipad上需要花费大约1分钟的时间。
private var fd: [[String:AnyObject]]? = [[String:AnyObject]]()
这是我的降序代码
self.fd = self.fd!.sort ({ (r1, r2) -> Bool in
let t = self.headers![b.tag - 10]
if r1[t.title] is String {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MMM-yyyy"
if dateFormatter.dateFromString("\(r1[t.title]!)") != nil {
let d1 = dateFormatter.dateFromString("\(r1[t.title]!)")
let d2 = dateFormatter.dateFromString("\(r2[t.title]!)")
return d1 > d2
} else {
// return "\(r1[t.title])".localizedStandardCompare("\(r2[t.title])") == .OrderedDescending
return "\(r1[t.title])" > "\(r2[t.title])"
}
} else if r1[t.title] is Int {
return Int(String(r1[t.title]!)) > Int(String(r2[t.title]!))
} else {
// return "\(r1[t.title])".localizedStandardCompare("\(r2[t.title])") == .OrderedDescending
return "\(r1[t.title])" > "\(r2[t.title])"
}})
升序
self.fd = self.fd!.sort ({
(r1, r2) -> Bool in
let t = self.headers![b.tag - 10]
if r1[t.title] is String {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MMM-yyyy"
if dateFormatter.dateFromString("\(r1[t.title]!)") != nil {
let d1 = dateFormatter.dateFromString("\(r1[t.title]!)")
let d2 = dateFormatter.dateFromString("\(r2[t.title]!)")
return d1 < d2
} else {
//return "\(r1[t.title])".localizedStandardCompare("\(r2[t.title])") == .OrderedAscending
return "\(r1[t.title])" < "\(r2[t.title])"
}
} else if r1[t.title] is Int {
return Int(String(r1[t.title]!)) < Int(String(r2[t.title]!))
} else {
// return "\(r1[t.title])".localizedStandardCompare("\(r2[t.title])") == .OrderedAscending
return "\(r1[t.title])" < "\(r2[t.title])"
}})
主要问题是大于10k的数据需要超过60秒。 请为我提供解决方案。
答案 0 :(得分:0)
您的排序的主要性能问题是您在比较闭包中执行转换。这将调用值格式化过程的指数次数(基于数组的大小)。
更有效的方法是使用.map()仅执行一次转换,并将sort函数应用于结果。
以下示例基于您的代码使用函数提取排序值,而.map()仅对数组中的每个元素执行一次此提取:
// only initialize your date formatter once
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MMM-yyyy"
// Extract the appropriate value and returns it in one of 3 types
// sorting will compare the 3 typed values knowing that only one of the 3
// will actually differ for a given data type
//
// The element is returned in the tupple in order to rebuild the
// array content after sorting on the 3 values
func getSortValues(_ element:[String:Any], _ id:String) -> ([String:Any], String, Int, TimeInterval)
{
let value = element[id]
var stringOrder = ""
var numericOrder = 0
var dateOrder = TimeInterval(0)
if let stringValue = value as? String,
let dateValue = dateFormatter.date(from:stringValue)
{
dateOrder = dateValue.timeIntervalSinceReferenceDate
}
else if let intValue = value as? Int
{
numericOrder = intValue
}
else if value != nil
{
stringOrder = "\(value!)"
}
return (element, stringOrder, numericOrder, dateOrder)
}
let columnId = headers![b.tag - 10]
fd = fd!.map{ getSortValues($0, columnId) }
.sorted{ $0.1 < $1.1 || $0.2 < $1.2 || $0.3 < $1.3 }
.map{ $0.0 }
应该快10到30倍(取决于阵列的大小)。