我有一个 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