Swift 使用哪种通用排序算法?它在排序数据上表现不佳

2024-05-19

我一直在挑选和探索 Swift 标准库sort()其函数为Array类型。令我惊讶的是,我注意到它在已经排序的数据上表现不佳。

对数组进行排序Int打乱顺序似乎比对已经排序的同一个数组进行排序快 5 倍。对已打乱顺序的对象数组进行排序比对已按排序顺序的相同对象进行排序大约快 4 倍(对对象数组进行排序与Int我确信数组使用不同的算法,所以我对两者进行了排序以消除偏差)。

结果如下:

Shuffled Int array sort time: 1.3961209654808
Shuffled ColorObject array sort time: 3.14633798599243
NOnshuffled Int array sort time: 7.34714204072952
NOnshuffled ColorObject array sort time: 10.9310839772224

以下是我的代码供参考:

class ElapsedTimer {

    let startTime: CFAbsoluteTime
    var endTime: CFAbsoluteTime?

    init() {
        startTime = CFAbsoluteTimeGetCurrent()
    }

    func stop() -> CFAbsoluteTime {
        endTime = CFAbsoluteTimeGetCurrent()
        return duration!
    }

    var duration: CFAbsoluteTime? {
        if let endTime = endTime {
            return endTime - startTime
        } else {
            return nil
        }
    }
}

public class CountedColor {
    public private(set) var count: Int
    public private(set) var color: UIColor

    public init(color: UIColor, colorCount: Int) {
        self.count = colorCount
        self.color = color
    }
}

var distributedIntArray = [Int]()

for value in 1..<1000000 {
    distributedIntArray.append(value)
}

var distributedCountedColorArray = distributedIntArray.map{ CountedColor(color: UIColor.white, colorCount: $0) }

distributedCountedColorArray.shuffle()
distributedIntArray.shuffle()

var timer = ElapsedTimer()
distributedIntArray.sort()
print("Shuffled Int array sort time: \(timer.stop())")
timer = ElapsedTimer()

distributedCountedColorArray.sort{ return $0.count < $1.count }
print("Shuffled Color array sort time: \(timer.stop())")
timer = ElapsedTimer()

distributedIntArray.sort()
print("NOnshuffled Int array sort time: \(timer.stop())")
timer = ElapsedTimer()

distributedCountedColorArray.sort{ return $0.count < $1.count }
print("Non shuffled Color array sort time: \(timer.stop())")

我的阵列shuffle()方法是从这个帖子 https://stackoverflow.com/questions/37843647/shuffle-array-swift-3/37843901. My ElapsedTimer简单地包装和使用CACurrentMediaTime()功能。

我的问题是为什么我会看到这种行为?特别是当我对对象数组进行排序时,它肯定应该使用通用排序。 Swift 使用哪种通用排序算法?它肯定不可能是像归并排序那样最坏情况和平均情况相同的情况。


斯威夫特使用介绍 https://en.wikipedia.org/wiki/Introsort。看着源代码 https://github.com/apple/swift/blob/master/stdlib/public/core/Sort.swift.gyb我们看到所选的主元是第一个元素。 Introsort 的维基百科页面说道:

(...),关键操作之一是选择枢轴: 列表围绕其进行分区的元素。最简单的枢轴 选择算法是取第一个或最后一个元素 列表作为枢轴,导致排序或排序的情况下表现不佳 几乎排序的输入。

因此,在给定实现选择的情况下,完全可以预测,Swift 的排序性能对于已排序的输入来说是最差的。

我为那些想要轻松重现OP声明的人建立了一个完整的基准:https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/extra/swift/sort https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/extra/swift/sort

作为参考,GNU ISO C++ 标准库使用中位数为 3 的主元(根据stl_algo.h标题)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift 使用哪种通用排序算法?它在排序数据上表现不佳 的相关文章

  • 我必须做什么才能使通过 HTTPS 提供的图像等内容缓存在客户端?

    我使用 Tomcat 作为服务器 使用 Internet Explorer 6 作为浏览器 我们应用程序中的网页大约有 75 张图像 我们正在使用 SSL 加载所有内容似乎非常慢 如何配置 Tomcat 以便 IE 缓存图像 如果您通过 h
  • 具有多种自定义单元格类型的 RxSwift 表视图

    我想知道是否有任何代码示例RxSwift当我可以在一个表视图中使用多个自定义单元格时 例如 我有两个部分 第一部分有 10 个单元格 类型为CellWithImage标识符和第二部分有 10 个带有类型的单元格CellWithVideo标识
  • 与 array_intersect 相反?

    是否有一个内置函数可以获取数组 1 中不存在于数组 2 中的所有成员 我知道如何以编程方式执行此操作 只是想知道是否有一个内置函数可以执行相同的操作 所以请不要提供代码示例 这听起来像是一份工作array diff http www php
  • 在 Javascript 中创建数组

    我对 javascript 不太熟悉 并且在用 javascript 制作 2d 或者也许我可能需要 3d 数组时遇到了一些麻烦 我目前需要收集 2 条信息 一个 ID 和一个值 因此我创建了以下内容 var myArray var id
  • 将一维数组转换为二维数组[重复]

    这个问题在这里已经有答案了 我正在开发一个程序 我必须将文本文件中的值读入一维数组 我已经成功获取该一维数组中的数字 m1 1 2 3 4 5 6 7 8 9 但我希望数组是 m1 1 2 3 4 5 6 7 8 9 您可以使用此代码 co
  • 通用类不会将委托调用转发给具体子类

    鉴于以下情况 protocol EntityType var displayString String get extension String EntityType var displayString String return self
  • 当内存排序放宽时,C++ 延迟会增加

    我在 Windows 7 64 位 VS2013 x64 发行版 上尝试内存排序 我想使用最快的同步来共享对容器的访问 我选择了原子比较和交换 我的程序产生两个线程 写入器推送到向量 读取器检测到这一点 最初我没有指定任何内存顺序 所以我假
  • UICollectionView 列的垂直偏移

    右图是我试图实现的目标 Does anyone know how I could achieve this on a two column UICollectionView I m able to discern my columns by
  • 在 viewWillAppear( ) 中获取空值,但在 viewDidLoad( ) 中获取有效值

    When print mess 被称为来自viewDidLoad函数 它打印预期的内容 但是当从viewWillAppear函数 它给出空输出 完成分配后标签也没有更新viewDidLoad 为什么是这样 主视图控制器 if segue i
  • 如何在构建持续时间和 RAM 使用方面优化 gradle 构建性能?

    我目前正在为我的多模块 Web 应用程序从 ant 切换到 gradle 目前看来当前版本的 Gradle M9 可能已经达到了极限 但也许 希望 这只是我对 Gradle 概念理解不够好或者不知道 神奇的性能提升开关 的问题 我很高兴收到
  • 我们是否需要使用 MappedByteBuffer.force() 将数据刷新到磁盘?

    我正在使用 MappedByteBuffer 来加速文件读 写操作 我的问题如下 我不确定是否需要使用 force 方法将内容刷新到磁盘 似乎没有 force getInt 仍然可以完美工作 好吧 因为这是一个内存映射缓冲区 我假设 get
  • MongoDB 查询 IN 对象数组

    我在检索两个集合之间的信息时遇到问题 第一个集合存储员工信息 id ObjectId 4f9643967f8b9a3f0a00005a birth date 1963 09 09 departments departments id Obj
  • Swift:在 Core Data 中存储自定义类的数组

    我是核心数据新手 但对于我的一个新项目 我想将我的数据保存到核心数据 我想创建一个 Reptile 类 其中包含几个自定义类数组 如果没有核心数据 我会得到这样的东西 import Foundation import UIKit class
  • 多级排序

    我有一个表 其中包含一些记录 其中包含名称 评级等字段 我首先想要根据评级将结果限制为 20 进行排序 然后在此结果集上想要进一步应用基于名称的排序 我知道要排序我们需要使用像这样的查询 Select from table order by
  • ggplot2 方面的内部排序

    我正在尝试在 ggplot2 中绘制一个方面 但我很难使不同方面的内部顺序正确 数据如下 head THAT EXT ID FILE GENRE NODE 1 CKC 1823 01 CKC Novels better 2 CKC 1824
  • 当 Firebase 函数以 Swift 结束时

    我在我的应用程序中使用 Firebase 它查询大量用户并获取所需的特定数据 但是当它开始查询时 其余功能也继续运行 而不仅仅是查询 所以我无法理解当它结束时 例如在这段代码中 ref observeEventType ChildAdded
  • 如何连接以逗号分隔的命名范围的返回值

    我花了几个小时试图找出如何连接命名范围中的返回值 但结果是 运行时错误 32 类型不匹配 作为一个新手 我仍在与数组作斗争 所以也许我忽略了一些细节 谢谢你帮助我 示例 B1 苯 B2 柴油 B3 混合动力 gt E1 汽油 E2 柴油 E
  • jQuery 相当于 underscore.js 的 groupBy

    jQuery 中是否有一个内置函数可以执行相当于http underscorejs org groupBy http underscorejs org groupBy 有什么解决方法吗 Thanks 不 jQuery 不是为数据处理而设计的
  • 从 dask 数据框中的日期时间序列获取年份和星期?

    如果我有一个 Pandas 数据框和一个日期时间类型的列 我可以按如下方式获取年份 df year df date dt year 对于 dask 数据框 这是行不通的 如果我先计算 像这样 df year df date compute
  • 小部件配置在 macOS 上不起作用

    我为我的 iOS 应用程序制作了一个小部件 效果很好 现在我正在将其移植到我的 macOS 应用程序中 但不知何故 小部件配置不起作用 这些项目已显示 但我无法以某种方式选择它们 查看屏幕截图 但请看一下我制作的视频 https youtu

随机推荐