对于下面的Perl代码,我需要提高效率,因为处理输入文件(包含数百万行数据)需要数小时。关于如何加快速度的任何想法?
鉴于两个文件,我想比较数据并打印匹配的行和不匹配的行。请注意,需要交替比较两列。
例如,
input1.txt
A B
C D
input2.txt
B A
C D
E F
G H
请注意: 第1行和第2行匹配(可互换);第3行和第4行不匹配
Output:
B A match
C D match
E F don't match
G H don't match
Perl代码:
#!/usr/bin/perl -w
use strict;
use warnings;
open INFH1, "<input1.txt" || die "Error\n";
open INFH2, "<input2.txt" || die "Error\n";
chomp (my @array=<INFH2>);
while (<INFH1>)
{
my @values = split;
next if grep /\D/, @values or @values != 2;
my $re = qr/\A$values[0]\s+$values[1]\z|\A$values[1]\s+$values[0]\z/;
foreach my $temp (@array)
{
chomp $_;
print "$_\n" if grep $_ =~ $re, $temp;
}
}
close INFH1;
close INFH2;
1;
有关如何提高此代码效率的任何想法都受到高度赞赏。谢谢!
答案 0 :(得分:1)
如果你有足够的内存,请使用哈希。如果在input1.txt中没有多次出现符号(即如果A B
在文件中,A X
不是),则以下内容应该有效:
#!/usr/bin/perl
use warnings;
use strict;
my %hash;
open my $F1, '<', 'input1.txt' or die $!;
while (<$F1>) {
my @values = split / /;
@hash{@values} = reverse @values;
}
close $F1;
open my $F2, '<', 'input2.txt' or die $!;
while (<$F2>) {
my @values = split / /;
my $value = $hash{$values[0]};
if ($value and $value eq $values[1]) {
print "Matches: $_";
} else {
print "Does not match: $_";
}
}
close $F2;
对于重复的值,我会使用散列哈希值。只需对符号进行排序,第一个符号将成为大型哈希中的键,第二个将成为子哈希中的键:
#!/usr/bin/perl
use warnings;
use strict;
my %hash;
open my $IN1, '<', 'input1.txt' or die $!;
while (<$IN1>) {
my @values = sort split;
undef $hash{$values[0]}{$values[1]};
}
close $IN1;
open my $IN2, '<', 'input2.txt' or die $!;
while (<$IN2>) {
chomp;
my @values = sort split;
if (exists $hash{$values[0]}{$values[1]}) {
print "$_ matches\n";
} else {
print "$_ doesn't match\n";
}
}
close $IN2;
答案 1 :(得分:0)
对于那些对列数量无关的另一种解决方案感兴趣的人:
#!/usr/bin/perl -w
use strict;
use warnings;
use 5.010;
open INFH1, "<", input1.txt" || die "Error\n";
my @storage = map {[sort split]} <$IN1>; # store content as matrix (each row sorted)
close INFH1;
open INFH2, "<input2.txt" || die "Error\n";
while(<INFH2>) {
chomp;
if(@{$storage[$.]} ~~ sort split) { # if stored matrix row is elementwise-equal to current line (each row sorted)
say "$_ matches";
}
else {
say "$_ doesn't match";
}
}
close INFH2;