【问题标题】:How to sort a very large array in C如何在C中对一个非常大的数组进行排序
【发布时间】:2011-08-01 01:50:17
【问题描述】:

我想在 C 中按大约四百万个 long longs 排序。通常我只会将 malloc() 一个缓冲区用作数组并调用 qsort() 但四百万 * 8 字节是一大块连续内存。

最简单的方法是什么?为此,我将轻松程度置于纯粹的速度之上。我不想使用任何库,结果需要在 Windows 和 Linux 下的普通上网本上运行。

【问题讨论】:

  • 价值从何而来,又将去往何处?你一开始就记住了它们吗?
  • 400 万乘以 8 约为 32 兆字节。它也不需要是连续的——您只需要为许多 4K 块的映射地址提供连续的地址空间。 IOW,malloc/qsort 应该没问题。
  • 32MB?这不是一个大块。那是一小块。
  • @hippietrail:数组将与您的代码相邻,但这只是内存管理硬件造成的假象。实际上,它被分配为更小的(4k,或在某些硬件上为 8K)块。底线:除非您使用的是真正内存受限的系统,否则不会有问题。
  • "640K 对于任何人来说应该都足够了。"

标签: c arrays sorting qsort large-data


【解决方案1】:

只需分配一个缓冲区并调用qsort。如今,即使在普通上网本上,32MB 也不是很大。

如果你真的必须拆分它:对较小的块进行排序,将它们写入文件,然后合并它们(合并对每个被合并的东西进行一次线性传递)。但是,真的,不要。只需排序即可。

(在 Knuth 的第 2 卷中对排序和合并方法进行了很好的讨论,它被称为“外部排序”。当 Knuth 写这篇文章时,外部数据本来应该在磁带上,但原理是与磁盘没有太大不同:您仍然希望 I/O 尽可能连续。SSD 的权衡有点不同。)

【讨论】:

  • 我唯一要补充的是,如果数据已经是磁盘上的原始二进制文件,您可以mmap(或等效项)而不是加载和写回它。但是,如果您在系统发生故障时关心数据的安全性,那么这可能是个坏主意。
  • qsort() 当然工作正常 - 我不知道我在担心什么。自从我从 C 语言转向脚本语言后,我可能不知道提供了多少内存管理,当时几兆字节就是很多 RAM。
【解决方案2】:

32 MB?那不是太大....快速排序应该可以解决问题。

【讨论】:

    【解决方案3】:

    如果可能,您最好的选择是防止数据无序。就像已经提到的那样,您最好将数据从磁盘(或网络或任何来源)直接读取到自组织容器中(一棵树,也许 std::set 会这样做)。

    这样一来,您就不必对大量内容进行分类,也不必担心内存管理。如果您知道容器所需的容量,则可以通过使用std::vector(initialcapacity) 或预先调用vector::reserve 来挤出额外的性能。

    最好建议您使用std::make_heapheapify 任何现有元素,然后使用push_heap 逐个元素添加(另请参阅pop_heap)。这与自排序集本质上是相同的范例,但是

    • 重复是可以的
    • 存储被“优化”为平面数组(非常适合例如共享内存映射内存映射文件

    (哦,小细节,注意堆上的sort_heap最多进行N log N比较,其中N是元素的数量)

    如果您认为这是一种有趣的方法,请告诉我。我真的需要更多关于用例的信息

    【讨论】:

    • Bloddy ... :) 我今天瞎了。好的,C 中必须有等价的方法;我希望这仍然有一些价值
    猜你喜欢
    • 2013-01-04
    • 2010-10-30
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 2018-06-14
    相关资源
    最近更新 更多