排序算法的简要调研

排序算法的代价

排序算法的时间代价主要由排序的时间复杂度决定。目前常见的排序算法根据其时间复杂度可以分为3类:O(n2)O(n^2)O(n2)O(nlogn)O(nlogn)O(nlogn)O(n)O(n)O(n)。其中O(n2)O(n^2)O(n2)复杂度的算法随着排序规模增大运行时间难以容忍,而O(n)O(n)O(n)复杂度的算法通常对序列的排序元素类型有一定限制,因此最常使用的排序算法复杂度为O(nlogn)O(nlogn)O(nlogn)。任何一个与排序元素类型无关的排序算法,其时间复杂度下界为O(nlogn)O(nlogn)O(nlogn)

如果希望排序算法和排序元素类型无关,排序只能通过值比较的方式完成。如果一个序列存在一个偏序关系≤\le(也即可值可比较),这个序列必定可以用基于值比较的排序算法进行排序。可以证明,完成排序所需要的值比较次数下界为O(nlogn)O(nlogn)O(nlogn)[1]。因此任何一个与排序元素类型无关的排序算法,其时间复杂度下界为O(nlogn)O(nlogn)O(nlogn)

目前较多排序算法的时间复杂度均为O(nlogn)O(nlogn)O(nlogn),但是它们面对不同规模的负载,运行在不同的硬件环境下时却各有优劣。这是因为排序算法的代价还与Cache/TLB 缺失、branch指令总数以及指令级并行性有关

常见排序算法及其应用场景

根据期望时间复杂度划分,目前的排序算法主要有以下几种:

  • O(n2)O(n^2)O(n2):冒泡排序,插入排序,选择排序,cyclesortcyclesortcyclesort
  • O(nlog2n)O(nlog^2n)O(nlog2n):希尔排序,原地归并排序
  • O(nlogn)O(nlogn)O(nlogn):归并排序,快速排序,推排序,二叉树排序,冒泡排序的变种combsortcombsortcombsort,插入排序的变种图书馆排序
  • O(n)O(n)O(n):基数排序,计数排序
  1. 当数据规模较小时,适合使用插入排序、combsortcombsortcombsort和选择排序。如果数据规模较小且两个数据元素比较代价低,交换代价高,例如型如<key,payload>的数据,其中payload长度远大于key,适合采用选择排序。
  2. 当数据规模较大时,适合采用快速排序,堆排序和归并排序。如果排序有稳定性需求时,适合采用归并排序。
  3. 当数据接近有序时,可采用插入排序或者冒泡排序。
  4. 当数据为整数时,适合采用基数排序。特别地,若整数数据值较小且重复值较多时,可采用计数排序。
  5. 当底层内存设备读写代价不对称时例如PCM内存时,适合采用选择排序和cyclesortcyclesortcyclesort,因为两者的总写次数为O(n)O(n)O(n).
  6. 当数据规模远大于可用内存空间时,采用外部多路归并。
排序算法的优化方向

目前的排序算法的优化研究主要有四个方向:指令级并行SIMD,线程级并行,新型内存技术,AI4Sort。

指令级并行

单指令多数据流(SIMD)是一种采用一个控制器来控制多个处理器,同时对一组数据(又称“数据向量”)中的每一个分别执行相同的操作从而实现空间上的并行性的技术。排序网络(Sorting Network)是由多个比较器组织成的网络结构,有n个输入端口和输出端口,可将n个无序数据输入转化为对应的有序输出。排序网络并行地工作,可大大提高排序地速度。

在这里插入图片描述

利用SIMD指令实现的排序网络,可对位于向量寄存器中的无序数据并行地排序,且向量排序过程没有分支跳转指令,这大大减少总排序过程的指令代价[2-3]。但是利用SIMD技术进行排序规模受限于向量寄存器的长度,因此SIMD实现的排序网络只可作为building block,它生成多个有序的小向量,然后外层将这多个有序向量进行归并。

quicksort并不适合利用SIMD来优化,因为quicksort的划分出来的子块并不均匀。对于归并排序算法而言,基本所有的子块大小都相等,因此当子块大小划分达到向量长度阈值时,可以采用SIMD来加速对子块的排序。

进程级并行:

多处理器并行排序算法主要分为两大类:merge-based 和 splitter-based算法。其中merge-based算法代表为bitonic sort,splitter-based算法代表有sample-sort和histogram-sort。此外还有radix-sort的并行版本。

merge-based的算法和splitter-based的算法均需要将排序工作量划分给多个处理器,从而成倍地减少总时间代价。两种算法地差别在于处理器将局部有序数据得到最终全序数据的方式:

  • merge-based算法在每个处理器执行局部数据的排序之后,采用并行merge的方式得到最终的有序数据。merge阶段中通信次数较多,通常为one-to-one通信模式;
  • splitter-based算法完成局部数据排序后,则尝试抽取数据中的p-1个数据作为splitter,根据它将每个处理器局部数据划分成p块,然后处理器执行一次all-to-all通信将对应块发送给对应处理器。此后处理器之间数据有序,每个处理器将接受到的p个数据块merge后得到最终结果。

在松耦合的处理器结点网络中,网络通信代价往往是系统的瓶颈所在,在这种系统下需要尽量减少数据传输量和传输次数,以及结点同步操作。splitter-based算法具有通信数据传输少,且同步代价低的优点,因此常常成为优先考虑的优化对象[4]。此外,很多研究均希望提高划分元素划分的均匀性,从而提高算法的扩展性和适应性。

新型内存:

非易失性内存(NVM)引入之后,传统的内存排序算法获得了新的研究契机。NVM技术存在诸多与DRAM大不相同的特性,其中影响排序性能的NVM特性主要为读写延迟稍高,读写代价不对称性和持久性。针对NVM内存排序研究可根据其考虑的内存架构划分:DRAM和NVM上下级架构,DRAM和NVM混合架构,纯NVM内存架构。

  • DRAM和NVM上下级架构下,内存排序的优化点在于减少DRAM与NVM之间的通信代价[5,6]。这类似传统外部排序需要减少DRAM和HDD/SSD的I/O代价,但不同点在于I/O粒度不再为page,同时I代价可能会低于O代价。外部多路归并排序十分适合这种场景,因为多路归并能显著减少总I/O次数,且能够适应DRAM空间较少的环境。文献[7]从形式化角度考虑了面对读写不对称架构下,多路归并排序通过以读换写的方式,减少归并阶段的趟数,从而减少对下层介质的总I/O次数。文献[5]的研究则同样考虑多路归并排序算法,并利用一些相关技术减少多路归并过程中的数据写回。
  • 在混合DRAM和NVM内存架构下,内存排序优化点在于如何将内存排序的读写集中在延迟更低的DRAM内存空间上去。文献[6]认为,多路归并排序是最适合混合内存架构下的排序算法。作者认为只需要让排序算法将混合内存空间当成上下层架构,充分减少DRAM和NVM之间的数据移动代价即load store次数即可。
  • 针对纯NVM内存架构的排序算法,其优化点会集中在如何在只引入O(n)O(n)O(n)的写的情况下,将算法时间复杂度降低O(nlogn)O(nlogn)O(nlogn)及以下(我们知道,选择排序和cycle排序的写代价仅为O(n)O(n)O(n),但是其总时间代价太差)。文献[8]研究了近似存储(Approximate computing,近似存储是牺牲写的精确性以降低写延迟提高写性能的存储技术,PCM就是这样的一种持久性近似存储)内存技术下不同排序算法性能。为了保证最终排序的正确性,在近似存储上的排序结果需要经过一个精炼阶段,这将与机器学习技术引入排序算法类似。
AI4Sort:

众所周知,机器学习技术大都是基于统计学和概率论的学习算法,因此并不能保证结果的绝对(100%)精确。而稳定的排序算法针对每个输入只有唯一的输出,这是一个精确地排序过程。应用机器学习技术提升排序算法性能,势必在需要排序最后引入一个精炼阶段。文献[9,10]提出了利用机器学习技术,从历史的排序数据中学习得出一个在无序数列的数据到其最终有序位置的映射,根据这个模型我们可以在线性时间内将无序数据排序成一个大致有序的数列,最后利用精炼步骤将这个大致有序的数据排序。由于机器学习模型排序数据大致有序,最终精炼步骤的时间代价可以大大缩减,在实际应用中,可能达到总体上线性的排序时延。

参考文献:

[1]. 基于比较的排序算法复杂度下限, https://www.zhihu.com/question/24516934/answer/28076722

[2]. Hiroshi Inoue, Kenjiro Taura: SIMD- and Cache-Friendly Algorithm for Sorting an Array of Structures. PVLDB 8(11): 1274-1285 (2015)

[3]. Michael Codish, Luís Cruz-Filipe, Markus Nebel, Peter Schneider-Kamp: Optimizing sorting algorithms by using sorting networks. Formal Asp. Comput. 29(3): 559-579 (2017)

[4]. Edgar Solomonik, Laxmikant V. Kalé: Highly scalable parallel sorting. IPDPS 2010: 1-12

[5]. Stratis Viglas: Write-limited sorts and joins for persistent memory. PVLDB 7(5): 413-424 (2014)

[6]. Mohammed Bey Ahmed Khernache, Arezki Laga, Jalil Boukhobza: MONTRES-NVM: An External Sorting Algorithm for Hybrid Memory. NVMSA 2018: 49-54

[7]. Guy E. Blelloch, Jeremy T. Fineman, Phillip B. Gibbons, Yan Gu, Julian Shun: Sorting with Asymmetric Read and Write Costs. SPAA 2015: 1-12

[8]. Shuang Chen, Shunning Jiang, Bingsheng He, Xueyan Tang: A Study of Sorting Algorithms on Approximate Memory. SIGMOD Conference 2016: 647-662

[9]. Zhu, Xiao-ke, Taining Cheng, Qi Zhang, Ling Liu, Jing He, Shaowen Yao and Wei Zhou. NN-sort: Neural Network based Data Distribution-aware Sorting. (2019).

[10]. The case for a learned sorting algorithm

<think>嗯,用户问的是如何写算法工程师的技术栈。首先,我需要明确用户的需求。可能他们正在准备简历或者面试,需要展示自己的技能。技术栈部分对于算法工程师来说确实很关键,因为要突出专业能力和项目经验。 接下来,我应该考虑技术栈的结构。通常分为几个部分,比如编程语言、算法基础、机器学习框架、数据处理、模型部署等等。用户可能希望有一个清晰的分类,让招聘方一目了然。 然后,我需要想想每个部分应该包含哪些具体的技术。比如编程语言里Python肯定是必须的,还有C++或Java可能在某些场景下需要。算法基础部分要包括数据结构、常用算法以及机器学习的基础知识,比如分类、回归、聚类这些。 机器学习框架方面,TensorFlow、PyTorch是主流,可能还要提到Keras或者Scikit-learn。数据处理工具比如Pandas、NumPy、Spark这些。深度学习部分可能要分CV、NLP或者其他领域,比如CV会用到OpenCV,NLP可能涉及Transformer、BERT等。 模型部署和优化也是重点,比如Docker、Kubernetes、TensorRT、ONNX这些工具。大数据和分布式计算可能需要Hadoop、Spark、Flink。云计算平台像AWS、Azure、阿里云也是常见的加分项。 另外,用户可能希望知道如何根据岗位调整技术栈。比如应聘CV工程师应该突出相关的框架和项目,而NLP岗位则需要Transformer、BERT等技术。同时,强调项目经验和量化成果也很重要,比如优化模型后准确率提升了多少,或者处理了多少数据量。 还要注意避免的问题,比如堆砌技术名词,不熟悉的技术不要写。排版要清晰,分类明确。可能用户希望技术栈既全面又有重点,所以需要分层次,核心技能放前面,相关技能简要提及。 最后,总结一下结构,给出一个模板,帮助用户组织自己的技术栈。可能还需要提醒用户结合自己的实际经验,真实展示技能,避免夸大。这样用户就能更有针对性地准备他们的技术栈部分,提升简历的效果了。</think>算法工程师的技术栈是简历和职业能力展示的核心部分,需要清晰、结构化地体现你的技术深度和岗位匹配度。以下是撰写建议和常见内容方向: --- ### **一、技术栈撰写原则** 1. **分类清晰**:按技术模块分层,避免杂乱堆砌。 2. **突出核心能力**:岗位相关的核心技能靠前,次要技能简写。 3. **量化成果**:结合项目说明技术落地效果(如准确率提升、耗时降低等)。 4. **避免冗余**:只写熟悉且有实践经历的技术,切忌堆砌名词。 --- ### **二、技术栈内容框架** #### **1. 编程语言** - **必写**:Python(算法岗核心语言)、SQL(数据处理) - **选写**:C++(高性能计算/部署)、Java/Scala(大数据场景)、Shell(脚本) - **示例**: ```markdown - 编程语言:Python(熟练使用NumPy/Pandas/Scikit-learn生态)、C++(熟悉STL及性能优化)、SQL(复杂查询与调优) ``` #### **2. 算法基础** - **数据结构与算法**:动态规划、图算法、排序/搜索优化 - **机器学习基础**:分类/回归/聚类算法(如XGBoost、SVM、K-Means)、特征工程、评估指标(AUC/F1等) - **深度学习**:CNN/RNN/Transformer、预训练模型(BERT、ResNet等)、损失函数设计 - **示例**: ```markdown - 算法基础:熟悉统计机器学习与深度学习模型,精通XGBoost调优与Transformer架构,复现过YOLOv5改进模型(mAP提升3%) ``` #### **3. 框架与工具** - **机器学习框架**:PyTorch(研究常用)、TensorFlow(工业部署)、LightGBM/CatBoost - **数据处理工具**:Pandas/NumPy、Spark(分布式计算)、Hive/Hadoop(大数据场景) - **部署与工程化**:Docker/Kubernetes、ONNX/TensorRT(模型压缩)、Flask/FastAPI(API开发) - **示例**: ```markdown - 框架工具:PyTorch(3年项目经验)、TensorFlow Serving(模型部署)、Airflow(流水线搭建)、Prometheus(服务监控) ``` #### **4. 领域细分技能(按岗位调整)** - **CV方向**:OpenCV、目标检测/图像分割、MMDetection/PaddleSeg - **NLP方向**:HuggingFace、文本分类/实体识别、LangChain/RAG - **推荐系统**:召回/排序策略、Faiss(向量检索)、CTR预估(DeepFM等) - **示例**: ```markdown - 计算机视觉:熟悉SAM/YOLO系列模型,实现过工业缺陷检测系统(漏检率<0.5%) ``` #### **5. 附加能力(加分项)** - **数学基础**:线性代数、概率统计、最优化理论 - **软技能**:技术文档写作、跨团队协作、技术调研与复现能力 - **工具链**:Git/GitLab CI/CD、Linux环境、LaTeX(论文写作) --- ### **三、技术栈模板示例** ```markdown **技术栈** - 编程语言:Python(主导5个算法项目)、C++(高性能计算)、SQL(亿级数据ETL) - 算法能力:精通推荐系统(召回/排序)、熟悉多模态对齐技术,复现CLIP改进模型(召回率+8%) - 深度学习框架:PyTorch(3年)、TensorRT(模型量化部署)、HuggingFace Transformers - 工程化:Docker/Kubernetes、Redis(缓存优化)、Prometheus+ELK(监控日志) - 领域工具:Faiss(亿级向量检索)、Airflow(任务调度)、Trino(跨库查询) - 数学基础:矩阵分解、概率图模型、最优化方法(SGD/Adam) ``` --- ### **四、注意事项** 1. **避免夸大**:不熟悉的技术注明「了解」而非「精通」。 2. **匹配岗位**:投递CV岗时弱化NLP相关技术,突出OpenCV/目标检测等。 3. **项目联动**:技术栈需与项目经历呼应(如写TensorRT则应有部署优化案例)。 通过清晰的技术栈展示,招聘方能快速判断你的能力与岗位需求的匹配度,建议结合自身经历灵活调整!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值