新しいスマートマッチ演算子があります:
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
my @x = (1, 2, 3);
my @y = qw(1 2 3);
say "[@x] and [@y] match" if @x ~~ @y;
Array::Compareについて:
内部的には、コンパレータは join を使用して両方の配列を文字列に変換し、 を使用して文字列を比較することにより、2 つの配列を比較しますeq
。
それは有効な方法だと思いますが、文字列比較を使用している限り、次のような方法を使用したいと思います。
#!/usr/bin/perl
use strict;
use warnings;
use List::AllUtils qw( each_arrayref );
my @x = qw(1 2 3);
my @y = (1, 2, 3);
print "[@x] and [@y] match\n" if elementwise_eq( \(@x, @y) );
sub elementwise_eq {
my ($xref, $yref) = @_;
return unless @$xref == @$yref;
my $it = each_arrayref($xref, $yref);
while ( my ($x, $y) = $it->() ) {
return unless $x eq $y;
}
return 1;
}
比較している配列が大きい場合、それらを結合すると、各要素を 1 つずつ比較するだけでなく、多くの作業が行われ、大量のメモリが消費されます。
更新:もちろん、そのようなステートメントをテストする必要があります。簡単なベンチマーク:
#!/usr/bin/perl
use strict;
use warnings;
use Array::Compare;
use Benchmark qw( cmpthese );
use List::AllUtils qw( each_arrayref );
my @x = 1 .. 1_000;
my @y = map { "$_" } 1 .. 1_000;
my $comp = Array::Compare->new;
cmpthese -5, {
iterator => sub { my $r = elementwise_eq(\(@x, @y)) },
array_comp => sub { my $r = $comp->compare(\(@x, @y)) },
};
elementwise_eq
これは、両方の配列のすべての要素を 1_000 回実行する必要がある最悪のシナリオであり、次のようになります。
レート イテレータ array_comp
イテレータ 246/秒 -- -75%
array_comp 1002/s 308% --
一方、最良のシナリオは次のとおりです。
my @x = map { rand } 1 .. 1_000;
my @y = map { rand } 1 .. 1_000;
レート array_comp イテレータ
array_comp 919/s -- -98%
イテレータ 52600/秒 5622% --
iterator
ただし、パフォーマンスはすぐに低下します。
my @x = 1 .. 20, map { rand } 1 .. 1_000;
my @y = 1 .. 20, map { rand } 1 .. 1_000;
レート イテレータ array_comp
イテレータ 10014/s -- -23%
array_comp 13071/秒 31% --
メモリ使用率は見ていません。