Arrays Perl中最有效的数组元素匹配过程?
我有两个数组Array1和Array2。阵列1包含约20000个非唯一元素。Array2包含约90000个独特元素。我试图计算数组1中也显示为数组2元素的元素数。下面的perl脚本成功地完成了这项工作,但速度很慢。是否有另一种计算Array2中存在的Array1元素数量的方法可能比这更快Arrays Perl中最有效的数组元素匹配过程?,arrays,performance,perl,element,matching,Arrays,Performance,Perl,Element,Matching,我有两个数组Array1和Array2。阵列1包含约20000个非唯一元素。Array2包含约90000个独特元素。我试图计算数组1中也显示为数组2元素的元素数。下面的perl脚本成功地完成了这项工作,但速度很慢。是否有另一种计算Array2中存在的Array1元素数量的方法可能比这更快 #!/usr/bin/perl use strict; use warnings; use autodie; # This program counts the total number of element
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
# This program counts the total number of elements in one array that exist in a separate array.
my $Original_Array_File = "U:/Perl/MasterArray.txt";
# Read in the master file into an array.
open my $file, '<', $Original_Array_File or die $!;
my @Array2 = <$file>;
close $file;
my $path = "C:/Files by Year/1993";
chdir($path) or die "Cant chdir to $path $!";
for my $new_file ( grep -f, glob('*.txt') ) {
open my ($new_fh), '<', $new_file;
my @Array1 = <$new_file>;
my @matched_array_count ;
foreach @Array1 {
++$matched_array_count if ($_ ~~ @Array2 ) ;
}
看起来您想要比较多个文件
您可以将其拆分为一个线程池,每个文件一个线程。或者,如果内存比较有限,可以将其中一个数组拆分为多个部分,并将每个部分发送到不同的线程。看起来您需要比较多个文件
您可以将其拆分为一个线程池,每个文件一个线程。或者,如果内存更紧张,您可以将其中一个阵列拆分为多个部分,并将每个部分发送到不同的线程。性能问题的主要来源是:
foreach @Array1 {
++$matched_array_count if ($_ ~~ @Array2 );
}
根据"基本法",
$string ~~ @array
就像
grep { $string ~~ $_ } @array
$string1 eq $string2
及
就像
grep { $string ~~ $_ } @array
$string1 eq $string2
将这些与原始代码片段结合在一起,我们得到如下结果:
foreach my $string1 @Array1 {
++$matched_array_count if grep { $string1 eq $_ } @Array2;
}
换句话说,取@Array1中的第一个元素并与@Array2中的每个元素进行比较,然后取@Array1中的第二个元素并与@Array2中的每个元素进行比较,依此类推。这对我很有用
scalar @Array1 * scalar @Array2
比较,约为18亿美元
在Perl中,这通常是通过哈希实现的。执行单个哈希查找比搜索数组中的每个元素要快得多。基本算法是:
将正在搜索的内容加载到haystack中。
在你的指针中循环你正在搜索和使用的内容,看看散列中是否有匹配的键。
在您的特定情况下,您可以将U:/Perl/MasterArray.txt的内容加载到散列中,然后执行以下操作:
scalar @Array1
散列查找,或~20000。这将比你现在拥有的要快得多
以下是在Linux字典文件中搜索单词的示例:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my $file = '/usr/share/dict/linux.words';
open my $fh, '<', $file or die "Failed to open '$file': $!";
my %haystack = map { chomp; $_ => 1 } <$fh>;
my $count;
while (<DATA>) {
chomp;
$count++ if exists $haystack{$_};
}
say $count;
__DATA__
foo
bar
foobar
fubar
显然,foobar是一个词。FUBAR是一个词,但小写的FUBAR不是
Smartmatch是实验性的
您还应该知道,从Perl 5.18.0开始:
Smart match在v5.10.0中添加,并在v5.10.1中进行了重大修改,这一直是一个常见的投诉点。尽管有许多方法可以使用它,但对于Perl的用户和实现者来说,它也被证明是有问题和令人困惑的。关于如何最好地解决这一问题,已经提出了一些建议。很明显,smartmatch几乎肯定会在未来改变或消失。不建议依赖其当前行为。重点补充
性能问题的主要来源是:
foreach @Array1 {
++$matched_array_count if ($_ ~~ @Array2 );
}
根据"基本法",
$string ~~ @array
就像
grep { $string ~~ $_ } @array
$string1 eq $string2
及
就像
grep { $string ~~ $_ } @array
$string1 eq $string2
将这些与原始代码片段结合在一起,我们得到如下结果:
foreach my $string1 @Array1 {
++$matched_array_count if grep { $string1 eq $_ } @Array2;
}
换句话说,取@Array1中的第一个元素并与@Array2中的每个元素进行比较,然后取@Array1中的第二个元素并与@Array2中的每个元素进行比较,依此类推。这对我很有用
scalar @Array1 * scalar @Array2
比较,约为18亿美元
在Perl中,这通常是通过哈希实现的。执行单个哈希查找比搜索数组中的每个元素要快得多。基本算法是:
将正在搜索的内容加载到haystack中。
在你的指针中循环你正在搜索和使用的内容,看看散列中是否有匹配的键。
在您的特定情况下,您可以将U:/Perl/MasterArray.txt的内容加载到散列中,然后执行以下操作:
scalar @Array1
散列查找,或~20000。这将比你现在拥有的要快得多
以下是在Linux字典文件中搜索单词的示例:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my $file = '/usr/share/dict/linux.words';
open my $fh, '<', $file or die "Failed to open '$file': $!";
my %haystack = map { chomp; $_ => 1 } <$fh>;
my $count;
while (<DATA>) {
chomp;
$count++ if exists $haystack{$_};
}
say $count;
__DATA__
foo
bar
foobar
fubar
显然,foobar是一个词。FUBAR是一个词,但小写的FUBAR不是
Smartmatch是实验性的
您还应该知道,从Perl 5.18.0开始:
Smart match在v5.10.0中添加,并在v5.10.1中进行了重大修改,这一直是一个常见的投诉点。尽管有许多方法可以使用它,但对于Perl的用户和实现者来说,它也被证明是有问题和令人困惑的。关于如何最好地解决这一问题,已经提出了一些建议。很明显,smartmatch几乎肯定会在未来改变或消失。不建议依赖其当前行为。重点补充
输入文件的格式是什么?行数?您应该首先使用分析脚本,以找出它在代码中花费的大部分时间。输入文件是大约200 KB到3 MB之间的.txt文件。它们是叙述性的讨论。我把它们分成六个单词的顺序。嗨,瑞克,我是v
由于您添加了一个,现在可以清楚地知道您的问题是什么了。通常的方法是将一个文件加载到哈希中,然后循环第二个文件,使用exists检查哈希中是否有与当前行匹配的键。确保两个文件中的每一行都被选中。另外,请注意,从Perl 5.18.0开始,您不应该使用~~。如果我之前的评论不清楚,~~是性能问题的原因。您正在进行@Array1*@Array2比较,或者在您的情况下,大约总共18亿。如果你使用我上面解释的方法,你只需要@Array1散列查找,或者~20000,如果散列适合内存的话,这会快很多?行数?您应该首先使用分析脚本,以找出它在代码中花费的大部分时间。输入文件是大约200 KB到3 MB之间的.txt文件。它们是叙述性的讨论。我把它们分成六个单词的顺序。嗨,瑞克,自从你添加了一个,我已经投票重新开始你的问题,现在你的问题已经很清楚了。通常的方法是将一个文件加载到哈希中,然后循环第二个文件,使用exists检查哈希中是否有与当前行匹配的键。确保两个文件中的每一行都被选中。另外,请注意,从Perl 5.18.0开始,您不应该使用~~。如果我之前的评论不清楚,~~是性能问题的原因。您正在进行@Array1*@Array2比较,或者在您的情况下,大约总共18亿。如果您使用我上面解释的方法,您将只进行@Array1散列查找,或者~20000次,如果散列适合内存,那么这将大大加快查找速度。