Perl:取消引用数组引用所花费的时间是否取决于数组的大小?

时间:2012-04-11 21:16:05

标签: perl reference dereference

好奇,如果有人知道(或可以轻松测试)引用然后取消引用数组所花费的时间。

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

显然没有合理的理由,但我遇到了不合理的代码:)

3 个答案:

答案 0 :(得分:7)

我执行的类似测试的基准测试给出了每个deref 10纳秒的订单。您发布的代码中只有deref,所以我们讨论的是0.000,000,010s差异。


Bah,差异很小,以至于我甚至无法可靠地判断哪一个更快!

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)

数组在50%的时间内更快,数组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%的时间做你想要测试的东西。

但同样,差异是如此之小,以至于无法衡量。有时阵列ref看起来更快,有时阵列显得更快。

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)

同样,数组在50%的时间内更快,数组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);

答案 1 :(得分:6)

一个天真的基准测试表明,将1到1,500,000之间的整数连接成一个字符串的不同方法之间没有明显的区别(除了错误的方式 - 下面没有显示)。< / p>

我确实想知道为什么人们需要创建这样一个字符串,但后来我很想知道。

#!/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";
    },
};

输出:

                Rate   interpolate derefref_join    plain_join
interpolate   4.76/s            --           -3%           -3%
derefref_join 4.89/s            3%            --           -1%
plain_join    4.92/s            4%            1%            --
C:\temp> perl -v

This is perl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
Binary build 1402 [295342] provided by ActiveState http://www.ActiveState.com
Built Oct  7 2011 15:49:44

Intel Core2 Duo T2300E@1.66Ghz, 2GB ram.

答案 2 :(得分:-1)

显然,由于处理器速度的原因,每台主机会有所不同。

衡量这一点的方法是使用time函数记录时间。然后创建并执行成千上万次解除引用操作的循环(因为测量单个解除引用将如此之快,您将无法测量它。)之后,再次记录时间。减去时间并除以循环次数。从中减去在没有取消引用的情况下完成循环所花费的时间。一点点数学,你就拥有它。