为什么我们需要外部排序?

时间:2015-02-06 04:35:02

标签: algorithm sorting virtual-memory external-sorting

外部排序的主要原因是数据可能比我们拥有的主内存大。但是,我们现在正在使用虚拟内存,虚拟内存将负责主内存和磁盘之间的交换。为什么我们需要外部排序吗?

3 个答案:

答案 0 :(得分:6)

外部排序算法可以有效地对大量数据进行排序(即使数据不适合物理RAM)。

虽然使用内存中排序算法和虚拟内存满足外部排序的功能要求(即,它将对数据进行排序),但它无法实现高效的非功能性要求。良好的外部排序可以最大限度地减少读取和写入外部存储的数据量(并且历史上也可以寻找时间),并且在不是为此设计的排序算法之上的通用虚拟内存实现将无法与设计为最小化IO。

答案 1 :(得分:1)

除了@ Anonymous的回答外部排序更好地针对更少的磁盘IO进行了优化,有时使用内存排序和使用虚拟内存是不可行的,因为虚拟内存空间小于文件的大小。

例如,如果你有一个32位系统(还有很多这些系统),并且你想要排序一个20 GB的文件,32位系统允许你有2 ^ 32~ = 4GB的虚拟地址,但是您尝试排序的文件无法适应。

当64位系统仍然不常见时,这曾经是一个真正的问题,并且对于旧的32位系统和一些嵌入式设备来说仍然是一个问题。


然而,即使对于64位系统,如前面的答案所示,外部排序算法针对排序的性质进行了更优化,并且与使操作系统“处理事情”相比,所需的磁盘IO要少得多。

答案 2 :(得分:0)

我使用Windows,在通用线路shell中,您可以运行" systeminfo",它会为我提供笔记本电脑的内存使用信息。

Total Physical Memory:     8,082 MB
Available Physical Memory: 2,536 MB
Virtual Memory: Max Size:  11,410 MB
Virtual Memory: Available: 2,686 MB
Virtual Memory: In Use:    8,724 MB

我只是编写了一个应用来测试我可以从笔记本电脑初始化的数据的最大尺寸

public static void BurnMemory()
{
    for(var i = 1; i <= 1024; i++)
    {
        long size = 1 << i;
        long t = 4 * size / (1 << 30);
        try
        {
            // 1 int32 takes 32 bit(4 byte) memmory, 
            var arr = new int[size];

            Console.WriteLine("Test pass initialize a array with size = 2^" + i.ToString());
        }
        catch(OutOfMemoryException err)
        {
            Console.WriteLine("Reach memory limitation when initialize a array with size = 2^{0} int32 = 4 x {1}B= {2}TB",i, size, t );
            break;
        }
    }
}

它似乎在尝试初始化大小为2 ^ 29的数组时终止。

Reach memory limitation when initialize a array with size = 2^29 int32 = 4 x 536870912B= 2TB

我从测试中得到了什么:

  • 达到内存限制并不困难。
  • 我们需要了解服务器的功能,然后决定是使用内存排序还是外部排序。