在 Perl 中,访问 1.6 亿行键/值对列表的最快方法是什么?



我有一个 1.6 米隆行的列表,如下所示:

N123HN  /var/foo/bar/baz/A/Alpha.file.1234.bin
N123HN  /var/foo/bar/baz/A/Alpha.file.1235.bin
N123KL  /var/foo/bar/baz/A/Alpha.file.1236.bin

我有一个Perl脚本,基本上只是在第二列上grep这些数据,作为查找第一列中的值的一种方式(然后它对"N123HN"值等执行其他魔术)。就像现在一样,我的应用程序花费大约 4 分钟来摄取文件并将其加载到一个巨大的哈希(键/值数组)中。虽然类似 grep 的函数本身由于显而易见的原因很慢,但运行此脚本最慢的部分是每次运行时都会大量摄取数据。

任何人都有任何聪明的想法,如何更快地访问这些数据?由于它只是两列的列表,因此关系数据库对于此用例来说似乎相当重量级。

我在这里重新编辑原始问题,因为将源代码粘贴到评论框中非常丑陋。

我用来摄取大文件的算法是这样的:

while(<HUGEFILE>)
    {
      # hugefile format:
      # nln N123HN ---- 1 0 1c44f5.4a6ee12 17671854355 /var/foo/bar/baz/A/Alpha.file.1234.bin 0
      next if /^(s)*$/;      # skip blank lines
      chomp;                  # remove trailing newline characters
      @auditrows = split;     # an array of entire rows, split on whitespace
      my $file_url = $auditrows[7];              # /var/foo/bar/baz/A/Alpha.file.1234.bin 
      my $tapenum  = "$auditrows[1] ";          # N123HN
      $tapenumbers{ $file_url } = $tapenum;      # key   = "/var/foo/bar/baz/A/Alpha.file.1234.bin" 
    }                                           # value = "N123HN"

4 分钟?!?!需要 7 秒!!

$ perl -E'say "N${_}HN  /var/foo/bar/baz/A/Alpha.file.$_.bin" for 1..1_600_000;' >file
$ time perl -E'my %h; while (<>) { my ($v,$k) = split; $h{$k}=$v; }' file
real    0m7.620s
user    0m7.081s
sys     0m0.249s

也许您没有足够的内存,这会导致交换?

您是否尝试过使用以第二列作为键和第一列作为值的哈希? 然后,您可以遍历大约 200 个文件路径,并直接在哈希中查找它们。 这可能比使用 grep 函数快得多。 下面是一个加载数据的快速脚本:

#!/usr/bin/perl
my %data;
open(my $fh, 'data') || die;
while (<$fh>) {
    my ($k, $path) = split;
    push @{$data{$path}}, $k;
}
print "loaded data: ", scalar(%data), "n";

我的perl很生疏,但是在我的笔记本电脑上运行得非常快,有160万行输入文件。

pa-mac-w80475xjagw% head -5 data
N274YQ  /var/foo/bar/baz/GODEBSVT/Alpha.file.9824.bin
N602IX  /var/foo/bar/baz/UISACEXK/Alpha.file.5675.bin
N116CH  /var/foo/bar/baz/GKUQAYWF/Alpha.file.7146.bin
N620AK  /var/foo/bar/baz/DHYRCLUD/Alpha.file.2130.bin
N716YD  /var/foo/bar/baz/NYMSJLHU/Alpha.file.2343.bin
pa-mac-w80475xjagw% wc -l data
 1600000 data
pa-mac-w80475xjagw% /usr/bin/time -l ./parse.pl
loaded data: 1118898/2097152
        5.54 real         5.18 user         0.36 sys
 488919040  maximum resident set size
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
    119627  page reclaims
         1  page faults
         0  swaps
         0  block input operations
         0  block output operations
         0  messages sent
         0  messages received
         0  signals received
         0  voluntary context switches
        30  involuntary context switches

相关内容

  • 没有找到相关文章

最新更新