perl サブルーチンへのパラメーターは @_ で渡されます。プログラムを読みやすくするために、私は常に次のパターンを使用して名前付きパラメーターを取得してきました。
sub foo1 {
my ($bar, $baz) = @_;
do_something($bar,$baz);
}
しかし、それは原因$_[0]
であり$_[1]
、コピーされます。$_[0]
上記のパターンでアクセスする代わりに直接アクセスする場合$bar
、呼び出し元のパラメーターへの値渡し/エイリアス アクセスがあり、参照渡しの通常の注意事項がありますが、はるかに高速です (以下のデモを参照)。
私は、このmy ($param1, $param2 ...) = @_;
パターンがパフォーマンス上の理由で悪いのではないかと疑っています。そのため、高速で読み取り可能なプログラムのどちらかを選択する必要があることがわかりましたが、これは不可能な選択です。
私は最終的に、パフォーマンスに重点を置いたサブを書き、$_[<n>]
それ以外はすべて上記のパターンで書きます。問題は、多くの場合、ボトルネックがどこにあるかを事前に知らないことです;-)
高速な名前付きパラメーターを取得する方法はありますか? または、この問題について正典と思われるものは何ですか?$_[0]
または$bar
?
付録: 速度のデモ
use Time::HiRes qw(time);
# Lets just do *something* with the parameters - here we just add up all
# their lengths
my $totalLength = 0;
sub foo1 {
# Access $_[0] directly - effectively call-by-reference
$totalLength += length($_[0]);
}
sub foo2 {
# Access a copy of $_[0] - effectively call-by-value - involves
# copying
my ($bar) = @_;
$totalLength += length($bar);
}
my $a = 'b' x 10_000;
my $t0 = time;
foreach (0..1_000_000) {
foo1($a);
}
printf "foo1 %2.6f\n", time - $t0;
$t0 = time;
foreach (0..1_000_000) {
foo2($a);
}
printf "foo2 %2.6f\n", time - $t0;
プリントアウト
foo1 0.329470
foo2 1.280364
foo1 は、コピーを回避するため、foo2 よりもほぼ 4 倍高速です$_[0]
。