Perl - 有效区分非常大的数组的最佳实践

时间:2013-11-25 04:58:30

标签: arrays perl key diff

在这里寻求建议。我是Perl的新手,正在寻找以最快的方式输入两个数组之间的差异。

我试图找到@ arr_1中的差异但@ arr_2中没有。

这两个数组将会很大,它们可以容纳6,000到8,000个元素,这些元素将保存唯一数据,数据类型为数组中的INT。由于这些阵列的大小,差异需要在CPU上快速而不是密集。

以下是我使用过的代码,我的问题是,是否有更快的方法在CPU上不那么密集?

找出差异

    my %diff3;    
    @diff3{ @arr_1 } = @arr_1;
    delete @diff3{  @arr_2};
    @diff = (keys %diff3);

提前感谢您,一旦我加快了Perl的速度,我期待着将其付清。

3 个答案:

答案 0 :(得分:2)

鉴于两个数组包含大约8k个唯一的整数元素,请考虑使用散列和grep来查找@arr_1中不在@arr_2中的元素。

模块Benchmark可用于使用模块Set::ScalarList::Compare,您的解决方案以及哈希和grep来比较此任务的时间:

use strict;
use warnings;
use Set::Scalar;
use List::Compare;
use Benchmark qw/cmpthese/;

my @arr_1 = 0 .. 8e3;
my @arr_2 = 2e3 .. 1e4;

sub setScalar {
    my $s1   = Set::Scalar->new(@arr_1);
    my $s2   = Set::Scalar->new(@arr_2);
    my $diff = $s1->difference($s2);
}

sub listCompare {
    my $lc = List::Compare->new( \@arr_1, \@arr_2 );
    my @diff = $lc->get_Lonly;
}

sub OPdiff {
    my %diff3;
    @diff3{@arr_1} = @arr_1;
    delete @diff3{@arr_2};
    my @diff = ( keys %diff3 );
}

sub hash_grep {
    my %arr_2_hash;
    undef @arr_2_hash{@arr_2};
    my @diff = grep !exists $arr_2_hash{$_}, @arr_1;
}

cmpthese(
    -5,
    {
        setScalar   => sub { setScalar() },
        listCompare => sub { listCompare() },
        OPdiff      => sub { OPdiff() },
        hash_grep   => sub { hash_grep() }
    }
);

输出:

              Rate   setScalar listCompare      OPdiff   hash_grep
setScalar   9.58/s          --        -69%        -98%        -98%
listCompare 31.1/s        225%          --        -92%        -94%
OPdiff       396/s       4034%       1172%          --        -21%
hash_grep    500/s       5119%       1506%         26%          --

Benchmark的结果显示从最慢到最快。对于这个差异化任务,很明显使用散列和grep是最快的,比你的解决方案快1.3倍,比List::Compare快15倍,比快{51}快比Set::Scalar

希望这有帮助!

答案 1 :(得分:1)

由于您的期望是每个数组只包含唯一元素,因此使用集合是有意义的。 Set::Scalar模块可以提供此功能。

use Set::Scalar;
$s1 = Set::Scalar->new(@arr_1);
$s2 = Set::Scalar->new(@arr_2);
$diff = $s1->difference($s2);

答案 2 :(得分:1)

您的代码找不到差异,它会找到@ arr_1但不是@ arr_2中的元素。数千个元素应该足够快。