swift - 在 Swift 中对大量文本记录进行排序的最快排序技术是什么?

标签 swift sorting

我正在使用 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 秒。 请给我一个解决方案。

最佳答案

排序的主要性能问题是您在比较闭包中执行转换。这将按指数次数调用值格式化过程(基于数组的大小)。

更有效的方法是使用 .map() 仅执行一次转换并将排序函数应用于结果。

这是一个基于您的代码的示例,使用函数提取排序值,并使用 .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 倍(取决于数组的大小)。

关于swift - 在 Swift 中对大量文本记录进行排序的最快排序技术是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42627098/

相关文章:

c++ - 如何在 C++ 中对包含负数和正数的字符串数组进行排序?

python - 用德语 Umlaute 对 Pandas 数据框进行排序

r - 自然排序以按列名称对数据框的列进行排序

java - 在前端或后端过滤分页排序

ios - 无法将类型 'Dictionary<String?, String?>.Keys' 的值分配给类型 'String'

ios - 升级到 XCode 7 后在 Bridging Header 中找不到头文件

swift - 向网络服务器发送参数

swift - 当 UICollectionViewCell 不在 View 中时尝试暂停视频

ios - 如何删除或隐藏 UITableViewController 的编辑 UIButton

javascript - 根据 1 个特定值的标识将对象拆分为多个有序数组