6

Perl 内部が配列を作成するために ref 値のコピーを作成するかどうか興味がありますか? たとえば、次の例では、区切り文字列の最後と最初の値が出力されます。

say @{[ split( q{\|}, q{bar|is|foo} ) ]}[-1,0];     # STDOUT: foobar\n
  • この操作は、最初にリストを生成しsplitて配列参照を作成し、逆参照するときに配列参照の値を新しい配列にコピーしますか?
  • 現在の配列参照をその場でモーフィングしますか?

逆参照は非常に一般的であるため、最適化されていると確信しています。最初にリストから配列を作成する場合と比較して、次のようにコストがかかることに興味があります。

my @parts = split q{\|}, q{bar|is|foo};
say @parts[-1,0];

目的:コードに深く入り込むことなく、基礎となる操作のアイデアを得る

4

2 に答える 2

1

vol7ron> Perl で配列参照を逆参照するのはどれくらいコストがかかりますか?

池上> 配列を逆参照するだけではありません。

vol7ron> しかし、問題はまだ残っています

繰り返しますが、これは役に立たない質問です。代替手段は、単に配列を逆参照することと、他の何かを逆参照することではありません。

しかし、あなたが主張するので、私にとっては 37 ns (37 10 億分の 1 秒) です。

use Benchmark qw( cmpthese );

my %tests = (
   deref => 'my @y = @$x;',
   none  => 'my @y = @x;',
);

$_ = 'use strict; use warnings; our $x; our @x; ' . $_
   for values %tests;

{
   local our @x = ();
   local our $x = \@x;
   cmpthese(-3, \%tests);
}

結果:

           Rate deref  none
deref 3187659/s    --  -12%
none  3616848/s   13%    --

各逆参照にかかる時間 = 1/3187659 秒 - 1/3616848 秒 = 37 ns

それは小さいです!配列の逆参照は、空の配列を逆参照して別の配列にコピーするのにかかる時間の 12% しか占めません!

この操作は最初に分割によってリストを生成し (1)、配列 ref を作成し (2)、逆参照するときに配列 ref の値を新しい配列にコピーしますか (3)?

  1. はい、splitリストを返します。スカラー コンテキストを除きます。

  2. [ ... ]参照を作成するだけでなく、配列も作成して値をコピーします。

  3. いいえ、逆参照は値をコピーしません。

現在の配列参照をその場でモーフィングしますか?

参照が別のものに変わったら、それは本当に悪いことです。どういう意味ですか?

于 2013-09-25T02:16:42.030 に答える