排序大于RAM大小的数据

时间:2011-12-21 03:34:16

标签: algorithm sorting data-structures

这是Google面试问题: 给定2台机器,每台机器具有64 GB RAM,包含所有整数(8字节),对整个128 GB数据进行排序。您可以假设少量额外的RAM。对此进行扩展以对存储在1000台机器中的数据进行排序。

我提出了外部排序。我们将整个数据划分为块并对它们使用合并排序。这是第一种块并将它们放回去并再次将它们合并并合并它们。有没有更好的办法?会有什么复杂性?

3 个答案:

答案 0 :(得分:4)

ChingPing为每个子集提出O(n log n)排序,然后进行线性合并(通过交换元素)。 Quicksort(以及大多数n log n排序)的问题是它们需要n个内存。我建议改为使用使用常量内存的SmoothSort,仍然在O(n log n)中运行。

最糟糕的情况是你有类似的地方:

setA = [maxInt .. 1]
setB = [0..minInt]

其中两个集合都是反向排序,但合并的顺序相反。

(IMO - 更清楚)对ChingPing解决方案的解释是:

Have a pointers 'pointerA', 'pointerB' initialized at the beginning of each array
While setA's pointer is not at the end
  if (setA[pointerA] < setB[pointerB])
    then { pointerA++; }
    else { swap(setA[pointerA], setB[pointerB]); pointerB++; }

现在应该对这些集进行排序。

答案 1 :(得分:0)

每个64 GB可以分别使用快速排序进行排序,然后使用外部存储器保持指针位于64GB阵列的头部,让我们考虑我们希望RAM1和RAM2按顺序拥有整个数据,保持递增指针在RAM1,如果它小于RAM2处的指针值,则将该值与RAM2交换,直到指针到达RAM1的末尾。

采用相同的概念对所有N个RAM进行排序。取对它们并使用上述方法排序。你剩下N / 2个排序的RAM。以递归方式使用上述相同的概念。

答案 2 :(得分:0)

2机器案件已有答案。

我假设要排序的128GB数据作为单个文件存储在单个硬盘驱动器(或任何外部设备)上。无论使用多少台计算机或硬盘驱动器,读取原始128GB文件并写入已排序的128GB文件所需的时间保持不变。唯一的节省发生在基于内部ram的排序期间,以创建排序数据块。与n + 1个硬盘驱动器合并到一个已分类的128GB文件到剩余硬盘驱动器的n路合并所需的时间再次保持不变,受限于将128GB分类文件写入剩余硬盘所需的时间硬盘。

对于n台机器,数据将分成128GB / n块。每台机器可以交替读取子块,一次可能是64MB,以减少随机访问开销,因此“最后”机器不会等待所有先前的机器在它们开始之前读取所有块

对于n台机器(每台64GB RAM)和n + 1台硬盘驱动器(n> = 4),每台机器可以使用具有O(n)时间复杂度的基数排序在n工作时创建32GB或更小的块同时使用硬盘驱动器,然后将n路合并到目标硬盘驱动器上。

有一个收益递减点限制了较大的n的利益。超出n>的某个地方16,内部合并吞吐量可能会大于磁盘I / O带宽。如果合并进程是cpu绑定而不是I / O绑定,那么在cpu开销中需要权衡并行创建块所需的时间,而合并开销大于I / O时间。