0

我有一个 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 脚本,它基本上只是在第二列中对这些数据进行 greps,作为在第一列中查找值的一种方式(然后它对“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

2 回答 2

8

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

也许您没有足够的内存并且导致交换?

于 2013-01-29T03:27:30.793 回答
1

您是否尝试过使用第二列作为键、第一列作为值的散列?然后您可以遍历 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
于 2013-01-29T03:46:20.113 回答