如何高效地对大文件进行两级排序?

问题描述 投票:0回答:4

我有一个非常大的文件,超过100GB(数十亿行),我想在内存有限的unix系统上尽快进行两级排序。这将是大型 Perl 脚本中的一个步骤,因此如果可能的话我想使用 Perl。

那么,我该怎么做呢?我的数据如下所示:

A    129
B    192
A    388
D    148
D    911
A    117

...但是对于数十亿行。我需要先按字母排序,然后按数字排序。使用unix排序会更容易吗,比如......

sort -k1,2 myfile

或者我可以用 Perl 来完成这一切吗?我的系统有 16GB 内存,但文件大约有 100GB。

感谢您的建议!

perl unix sorting
4个回答
8
投票

UNIX

sort
实用程序可以通过在磁盘空间上创建临时工作文件来处理对大数据(例如大于您的工作 16GB RAM)的排序。

因此,我建议按照您的建议简单地使用 UNIX

sort
,调用选项
-T tmp_dir
,并确保
tmp_dir
有足够的磁盘空间来容纳所有将要使用的临时工作文件。在那里创建的。

顺便说一句,这在之前的SO问题中进行了讨论。


1
投票

UNIX

sort
是对这种规模的数据进行排序的最佳选择。我建议使用快速压缩算法
LZO
。它通常分布为
lzop
。使用
-S
选项设置大排序缓冲区。如果您的磁盘比默认的
/tmp
设置更快,也设置
-T
。另外,如果您想按数字排序,则必须将排序数字排序定义为第二个排序字段。因此,您应该使用这样的行以获得最佳性能:

LC_ALL=C sort -S 90% --compress-program=lzop -k1,1 -k2n

0
投票

我有完全相同的问题! 经过大量搜索后,由于我不希望对 shell (UNIX) 有任何依赖以使其在 Windows 上可移植,所以我想出了以下解决方案:

#!/usr/bin/perl
use File::Sort qw(sort_file);
my $src_dic_name = 'C:\STORAGE\PERSONAL\PROJECTS\perl\test.txt';
sort_file({k => 1, t=>"    ", I => $src_dic_name, o => $src_dic_name.".sorted"});

我知道这是一篇旧帖子,但用解决方案更新它,以便很容易找到。

文档在这里


0
投票

正如 Hynek 已经说过的,gnu-sort 非常擅长处理大量数据,他们甚至使用几种不同的算法来预排序较小的块,然后用另一种算法将它们重新组合。

但是您可以使用 -S 内存选项使其变得更好。默认情况下,gnu-sort 最多使用大约 4-8MByte 的内存 - 来自 1990 年代的美好问候。

在我的 64GByte 机器上,我必须对 300GByte 文件进行排序。使用 -S 16G 将速度提高了 20 倍,并减少了大约 60-80% 的写入访问,如果您想减少闪存上的写入负载,这非常好。

只有一个缺点,至少在我的 64GByte-Cygwin-System 上,任何高于 16GByte 的东西都会产生不稳定的结果 - 突然内存不足、挂起、变得非常慢等等。这可能是 Windows 的问题,因为即使某些 Windows 软件也无法使用整个内存(我尝试使用 48GByte 字典进行 xz,但超过 32GByte 的所有内容也不可靠)。

© www.soinside.com 2019 - 2024. All rights reserved.