0

配列を参照してから逆参照するのにかかる時間を誰かが知っている (または簡単にテストできる) かどうかに興味があります。

my @foo = (0..1500000);     # (~1.5M nodes).
join('',@{\@foo});          # any noticeable time difference vs join('',@foo) ?

これには明らかに正当な理由はありませんが、私は不合理なコードに出くわしました:)

4

3 に答える 3

7

私が実行した同様のテストのベンチマークでは、deref ごとに 10 ナノ秒程度の結果が得られました。あなたが投稿したコードには deref しかないので、0.000,000,010 秒の違いについて話しています。


うーん、違いは非常に小さいので、どちらが速いかを確実に判断することさえできません!

Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.04 usr +  0.02 sys =  3.06 CPU) @ 11.12/s (n=34)
 array_ref:  3 wallclock secs ( 3.13 usr +  0.00 sys =  3.13 CPU) @ 11.48/s (n=36)

Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.06 usr +  0.03 sys =  3.09 CPU) @ 11.33/s (n=35)
 array_ref:  3 wallclock secs ( 3.12 usr +  0.05 sys =  3.17 CPU) @ 11.37/s (n=36)

Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.06 usr +  0.00 sys =  3.06 CPU) @ 11.45/s (n=35)
 array_ref:  3 wallclock secs ( 3.18 usr +  0.00 sys =  3.18 CPU) @ 11.31/s (n=36)

Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.09 usr +  0.00 sys =  3.09 CPU) @ 11.66/s (n=36)
 array_ref:  3 wallclock secs ( 3.17 usr +  0.00 sys =  3.17 CPU) @ 11.37/s (n=36)

array は 50% の確率で速くなり、array ref は 50% の確率で速くなります。

use strict;
use warnings;

use Benchmark qw( timethese );

my %tests = (
   array_ref => 'my $x = join("", @$foo);',
   array     => 'my $x = join("", @foo);',
);

$_ = 'use strict; use warnings; our $foo; our @foo; ' . $_
   for values(%tests);

our @foo = 1..1_500_000;
our $foo = \@foo;

timethese(-3, \%tests);

これは、投稿したものよりも優れたテストです。あなたが投稿した唯一のものは、あなたがテストしたいことに費やした時間の 1% 未満でした。

繰り返しますが、違いは非常に小さいため、測定できません。配列参照の方が高速に表示される場合もあれば、配列の方が高速に表示される場合もあります。

Actual speed is actually 1000x larger than indicated.
Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.09 usr +  0.00 sys =  3.09 CPU) @ 1015.54/s (n=3136)
 array_ref:  3 wallclock secs ( 3.24 usr +  0.00 sys =  3.24 CPU) @ 1040.99/s (n=3378)

Actual speed is actually 1000x larger than indicated.
Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.25 usr +  0.00 sys =  3.25 CPU) @ 1011.09/s (n=3281)
 array_ref:  3 wallclock secs ( 3.07 usr +  0.00 sys =  3.07 CPU) @ 1022.13/s (n=3141)

Actual speed is actually 1000x larger than indicated.
Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.29 usr +  0.00 sys =  3.29 CPU) @ 1020.96/s (n=3361)
 array_ref:  3 wallclock secs ( 3.20 usr +  0.00 sys =  3.20 CPU) @ 1016.26/s (n=3250)

Actual speed is actually 1000x larger than indicated.
Benchmark: running array, array_ref for at least 3 CPU seconds...
     array:  3 wallclock secs ( 3.07 usr +  0.00 sys =  3.07 CPU) @ 1053.03/s (n=3237)
 array_ref:  4 wallclock secs ( 3.23 usr +  0.00 sys =  3.23 CPU) @ 1006.50/s (n=3250)

繰り返しますが、array は 50% の確率で高速であり、array ref は 50% の確率で高速です。

use strict;
use warnings;

use Benchmark qw( timethese );

my %tests = (
   array_ref => 'my $x = join("", @$foo);',
   array     => 'my $x = join("", @foo);',
);

$_ = 'use strict; use warnings; our $foo; our @foo; for (1..1000) { '.$_.' }'
   for values(%tests);

our @foo = 1..15;
our $foo = \@foo;

print("Actual speed is actually 1000x larger than indicated.\n");
timethese(-3, \%tests);
于 2012-04-11T22:10:16.777 に答える
6

単純なベンチマークは、1 から 1,500,000 までの整数を 1 つの文字列に連結するさまざまな方法の間に識別可能な違いがないことを示しています (ただし、間違った方法があります -- 以下には示されていません)。

なぜそのような文字列を作成する必要があるのか​​ 疑問に思いますが、それでは多くの疑問があります.

#!/usr/bin/env perl

use strict; use warnings;
use Benchmark qw( cmpthese );

my @nodes = (1 .. 1_500_000);

cmpthese -5, {
    derefref_join => sub {
        my $str = join('', @{ \@nodes });
    },
    plain_join => sub {
        my $str = join('', @nodes);
    },
    interpolate => sub {
        local $" = '';
        my $str = "@nodes";
    },
};

出力:

                レート補間 derefref_join plain_join
補間 4.76/s -- -3% -3%
derefref_join 4.89/秒 3% -- -1%
plain_join 4.92/s 4% 1% --
C:\temp> perl -v

これは、MSWin32-x86-multi-thread 用にビルドされた perl 5、バージョン 14、subversion 2 (v5.14.2) です。
ActiveState http://www.ActiveState.com が提供するバイナリ ビルド 1402 [295342]
2011 年 10 月 7 日 15:49:44 に構築

Intel Core2 Duo T2300E@1.66Ghz、2GB RAM。
于 2012-04-11T22:15:18.220 に答える
-1

明らかに、プロセッサの速度により、ホスト マシンごとに異なります。

これを測定する方法は、time関数を使用して時間を記録することです。次に、数万回の逆参照操作のループを作成して実行します (単一の逆参照を測定するのは非常に高速であるため、測定することはできません)。その後、時間を再度記録します。回数を引き、ループの回数で割ります。この値から、逆参照なしでループを通過するのにかかる時間を引きます。ちょっとした数学、そしてあなたはそれを持っています。

于 2012-04-11T21:21:35.047 に答える