外部排序

外部排序指的是大文件排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。

一般来说外排序分为两个步骤:预处理和合并排序。首先,根据可用内存的大小,将外存上含有n个纪录的文件分成若干长度为t的子文件(或段);其次,利用内部排序的方法,对每个子文件的t个纪录进行内部排序。这些经过排序的子文件(段)通常称为顺串(run),顺串生成后即将其写入外存。这样在外存上就得到了m个顺串(m=[n/t])。最后,对这些顺串进行归并,使顺串的长度逐渐增大,直到所有的待排序的记录成为一个顺串为止。

初始顺串

预处理阶段最重要的事情就是选择初始顺串。通常使用的方法为置换选择排序,它是堆排序的一种变形,实现思路同STL的partial_sort。步骤如下:

(1)初始化堆

从磁盘读入M个记录放到数组RAM中;

设置堆末尾标准LAST=M-1;

建立最小值堆。

(2)重复以下步骤直到堆为空

把具有最小关键码值的记录Min也就是根节点送到输出缓冲区;

设R是输入缓冲区中的下一条记录,如果R的关键码大于刚刚输出的关键码值Min,则把R放到根节点,否则使用数组中LAST位置的记录代替根节点,并将刚才的R放入到LAST所在位置,LAST=LAST-1;

(3)重新排列堆,筛出根节点。

如果堆的大小是M,一个顺串的最小长度就是M个记录,因为至少原来在堆中的那些记录将成为顺串的一部分,如果输入时逆序的,那么顺串的长度只能是M,最好情况输入是正序的,有可能一次性就能把整个文件生成一个顺串,由此可见生成顺串的长度是大小不一的,但是每个顺串却是有序的,利用扫雪机模型能够得到平均顺串的长度为2M。

外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行归并排序。

合并排序

(1) 二路合并排序

二路合并是最简单的合并方法,合并的实现与内排序中的二路归并算法并无本质区别,下面通过具体例子,分析二路合并外部排序的过程。

有一个含有9000个纪录的文件需要排序(基于关键字)。假定系统仅能提供容纳1800个纪录的内存。文件在外存(如磁盘)上分块存储,每块600个纪录。外部排序的过程分为生成初始顺串和对顺串进行归并排序两个阶段。在生成初始顺串阶段,每次读入1800个纪录(即3段)待内存,采用内排序依次生成顺串依次写入外存储器中。

顺串生成后,就开一开始对顺串进行归并。首先将内存等分成3个缓冲区,每个缓冲区可容纳600个纪录,其中两个为输入缓冲区,一个为输出缓冲区,每次从外存读入待归并的块到输入缓冲取,进行内部归并,归并后的结果送入输出缓冲区,输出缓冲区的记录写满时再将其写入外存。若输入缓冲区中的纪录为空,则将待归并顺串中的后续块读入输入缓冲区中进行归并,直到待归并的两个顺串都已归并为止。重复上述的归并方法,由含有5块(每块上限1800个记录)的顺串经二路归并的一遍归并后生成含有3块(每块上限3600个记录)的顺串,再经过第二遍……第s遍(s=[],m为初始顺串的个数),生成含有所有记录的顺串,从而完成了二路归并外部排序。

对文件进行外部排序的过程中,因为对外存的读写操作所用的操作的时间远远超过在内存中产生顺串和合并所需的时间,所以常用对外存的读写操作所用的时间作为外部排序的主要时间开销。分析一下上述二路归并排序的对外存的读写时间。初始时生成5个顺串的读写次数为30次(每块的读写次数为2次)。

类似地,可得到二路、三路……多路合并方法。

(2) 多路替代选择合并排序

采用多路合并技术,可以减少合并遍数,从而减少块读写次数,加快排序速度。但路数的多少依赖于内存容量的限制。此外,多路合并排序的快慢还依赖于内部归并算法的快慢。

设文件有n个纪录,m个初始顺串,采用k路合并方法,那么合并阶段将进行遍合并。k路合并的基本操作是从k个顺换的第一个纪录中选出最小纪录(即关键字最小的纪录),把它从输入缓冲区移入输出缓冲区。若采用直接选择方式选择最小元,需要k-1次比较,遍合并共需n(k-1)=次比较。由于随k的增长而增长,则内部归并时间亦随k的增大而增大,这将抵消由于增大k而减少外存信息读写时间所得的效果。若在k个纪录中采用树形选择方式选择最小元,则选择输出一个最小元之后,只需从某叶到根的路径上重新调整选择树,即可选择下一个最小元。重新构造选择书仅用O()次比较,于是内部合并时间O(n)=O(),它与k无关,不再随k的增大而增大。

常见的有基于“败者树”的多路替代选择合并排序方法。

其他算法

外归并排序法并不是唯一的外排序算法。另外还有外分配排序,其原理类似于内排序中的桶排序。在归并排序和桶排序之间存在数学上的某种对偶性。此外还有一些不耗费附加磁盘空间的原地排序算法。

优化性能

计算机科学家吉姆·格雷的SortBenchmark网站用不同的硬件、软件环境测试了实现方法不同的多种外排序算法的效率。效率较高的算法具有以下的特征:

  • 并行计算

    • 用多个磁盘驱动器并行处理数据,可以加速顺序磁盘读写。
    • 在计算机上使用多线程,可在多核心的计算机上得到优化。
    • 使用异步输入输出,可以同时排序和归并,同时读写。
    • 使用多台计算机用高速网络连接,分担计算任务。
  • 提高硬件速度

    • 增大内存,减小磁盘读写次数,减小归并次数。
    • 使用快速的外存设备,比如15000 RPM的硬盘或固态硬盘。
    • 使用性能更优良个各种设备,比如使用多核心CPU和延迟时间更短的内存。
  • 提高软件速度

    • 对于某些特殊数据,在第一阶段的排序中使用基数排序。
    • 压缩输入输出文件和临时文件。

内部排序

考虑到外部排序涉及的待排序记录数量大,可以采取分治的思想(即先分解, 再递归求解, 然后合并) 将其划分成几段合适的待排序记录,然后对每一小段采用内部排序方法。换句话说,就是将外部排序转化为内部排序,所以为了进一步研究外部排序, 需先对内部排序进行深入的讨论。如果在排序过程中依据不同原则对内部排序方法进行分类,则大致可分为插入排序、冒泡排序、选择排序、归并排序和快速排序等5类。

通常, 排序记录存储具有如下3种形式:

1、待排序的一组记录存放在地址连续的一组存储单元上,它类似于线性表的顺序存储结

构,在序列中相邻的2个记录Rj 和R j+ 1 ( j = 1, 2,……, n - 1) 其存储位置也相邻。这种存储方式中,记录之间的次序关系由其存储的位置决定,排序通过移动记录来实现。

2、一组待排序记录存放在静态链表中,记录之间的次序关系由指针指示, 则实现排序不需要移动记录,仅需移动指针即可。

3、待排序记录本身存储在一组地址连续的存储单元内, 同时另设一个指示各个记录存储位置的地址向量, 在排序过程中不移动记录本身,而移动地址向量中这些记录的地址, 在排序结束之后再按照地址向量中的值调整记录的存储位置。

外部排序——大文件排序相关推荐

  1. python大文件排序_Python如何实现大文件排序?Python大文件排序的实现方法

    Python如何实现大文件排序?Python大文件排序的实现方法 本文实例讲述了Python实现大文件排序的方法.分享给大家供大家参考.具体实现方法如下: import gzip import os ...

  2. 可以对大文件排序的排序算法

    Z-Tree是一个可以对大数据排序的数据结构.Z-Tree对大数据排序算法的时间复杂度是O(n). Z-Tree可以取代Hash表实现关键字(Key)到值(Value)的映射. Z-Tree Demo ...

  3. 处理大文件排序的方式--外部排序

    引言   一般来说,对一个数组的排序,我们常用冒泡排序.快速排序.堆排序等算法进行排序.这样的数组能够一次性加载到内存中,使用上述的排序算法就能轻而易举进行排序,所以上述的排序算法可以称之为堆内排序. ...

  4. 内存不足时的大文件排序算法(spark shuffle的排序算法)

    1.问题场景 例如:当前磁盘2T,内存16G,文件大小500G.现在需要对500G的大文件进行排序,并存道另一个文件中. 抽象:当前有包含10000行数的文件,再只能使用长度为1000的数组的前提下, ...

  5. python文件信息排序_python文件排序的方法总结

    在python环境中提供两种排序方案:用库函数sorted()对字符串排序,它的对象是字符:用函数sort()对数字排序,它的对象是数字,如果读取文件的话,需要进行处理(把文件后缀名'屏蔽'). (1 ...

  6. python大文件排序_python实现按创建时间对文件排序

    测试中,测试log是经常需要保存一段时间以便于后续查询,但是如果一段时间不删除,会导致硬盘空间变小而影响自动化测试,通常空间太小,自动化测试case就不能调用了,或者即使调用,可能会引起新测试的log ...

  7. python大文件排序_Python实现大文件排序的方法

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  8. python大文件排序_Python 大文件排序

    1.[代码][Python]代码 import gzip import os from multiprocessing import Process, Queue, Pipe, current_pro ...

  9. 按一行一行的方法将一个文本文件复制到另一个文件中_大文件上的结构化数据计算示例...

    [摘要] 本文分析大文件计算的实现原理,如过滤.聚合计算.添加计算列.排序.分组聚合.topN 等,以及利用并行计算来提高计算速度,并用 esProc SPL 举例说明如何用简洁的脚本实现大文件计算. ...

最新文章

  1. Collection View Programming Guide for iOS---(四)---Using the Flow Layout
  2. 13、不同存储引擎的数据表在文件系统里是如何表示的?
  3. 华为交换机忘了密码如何恢复
  4. App推广中如何寻找200个以上渠道
  5. HDUOJ 2089
  6. uniapp点击图片放大_想要放大镜将图片放大的效果?你只需这么做即可!
  7. 1.5亿元奖金,给了这50位青年科学家
  8. 2020年餐饮B2B服务产业创新报告
  9. 本地页面存1天的缓存
  10. react dispatch_梳理下redux、mobx 在react的应用
  11. 题目1006:ZOJ问题
  12. 离散数学计算机科学与技术答案,2计算机科学与技术专业本科离散数学期末复习题2...
  13. ad15的stc元件库_常用的Altium Designer AD09 AD14 AD18元件库 原理图库(543个)+PCB封装库(509个)...
  14. spa文件转换html,前端微服务化解决方案2 - Single-SPA
  15. STM32F4+ESP8266拟辉光钟设计(二)WS2812灯光控制
  16. QQ心跳包格式分析 监听局域网QQ号代码
  17. 2、解读中台 -- 中台的作用
  18. 神经网络长什么样不知道?这有一份简单的 pytorch可视化技巧
  19. 一篇文章带你走近Android自定义view
  20. scrapy_splash动态ip代理和请求头的动态修改

热门文章

  1. c语言中如何读取文件的内容,急急急!!!如何读取文件中的相关内容
  2. TensorFlow2 实现神经风格迁移,DIY数字油画定制照片,面试必问知识点
  3. 微信小程序在特殊机型上崩溃的问题
  4. 横看成岭侧成峰,远近高低各不同
  5. 拜拜了,浮动布局-基于display:inline-block的列表布局
  6. android 2g内存,追求极致流畅体验 2G内存安卓手机推荐
  7. 错误 C2447 “{”: 缺少函数标题(是否是老式的形式表?)
  8. 软件测试如何选择第三方软件测评公司
  9. 神经学家的探寻:这就是机器如何拥有意识的方法 | 精选
  10. 操作系统-内存管理(快表的地址变换机构,两级页表,虚拟内存的基本概念,基本页式管理下的页表和页面置换算法)