简体   繁体   English

在Perl中取消引用数组引用有多昂贵?

[英]How expensive is it to dereference an array ref in Perl?

I'm curious if Perl internals creates a copy of the ref values to create the array? 我很好奇Perl internals是否创建了ref值的副本来创建数组? For example, the following outputs the last and first value of a delimited string: 例如,以下输出分隔字符串的最后一个和第一个值:

say @{[ split( q{\|}, q{bar|is|foo} ) ]}[-1,0];     # STDOUT: foobar\n
  • Does the operation first generate a list via split and create an array ref, then copy the values of the array ref into a new array when dereferencing? 操作是否首先通过split生成列表并创建数组引用,然后在解除引用时将数组ref的值复制到新数组中?
  • Does it morph the current arrayref in place? 它是否将当前的arrayref变形?

Because dereferencing is so common I'm sure it's optimized, I'm just curious how expensive it is versus creating an array from the list initially, like: 因为解除引用是如此常见,我确信它已经过优化,我只是好奇它与最初从列表中创建数组相比有多昂贵,例如:

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

Purpose: getting an idea of the underlying operations w/o getting too deep into the code 目的:了解底层操作,而无需深入了解代码

Here is a Benchmark 这是一个基准

#!/usr/bin/perl 
use strict;
use warnings;
use 5.010;
use Benchmark qw(:all);

my @list = ('foo')x1_000_000;
my $str = join('|',@list);
my $count = -2;
cmpthese($count, {
    'deref' => sub {
        my $parts = [ split( q{\|}, $str ) ];
        my @res = @$parts[-1,0];
    },
    'array' => sub {
        my @parts = split q{\|}, $str;
        my @res =  @parts[-1,0];
    },
});

I just change say to an assignement. 我只是改变对一个人的say
Windows 7, perl 5.14.2 Windows 7,perl 5.14.2

        Rate deref array
deref 2.02/s    --  -38%
array 3.23/s   60%    --

Depending of environment, I get 根据环境,我得到了
Linux 64 bit, perl 5.14.2 Linux 64位,perl 5.14.2

        Rate deref array
deref 3.00/s    --  -35%
array 4.65/s   55%    --

and Linux 32 bit, perl 5.8.4 和Linux 32位,perl 5.8.4

        Rate array deref
array 1.96/s    --  -35%
deref 3.00/s   53%    --

vol7ron> How expensive is it to dereference an array ref in Perl? vol7ron>在Perl中取消引用数组引用有多贵?

ikegami> You're doing more than just dereferencing an array. ikegami>你所做的不仅仅是取消引用数组。

vol7ron> But the question still stands vol7ron>但问题仍然存在

Again, this is a useless question. 同样,这是一个无用的问题。 The alternative is never between simply dereferencing an array and something else. 替代方案永远不会简单地取消引用数组和其他东西。

But since you insist, it's 37 ns (37 billionths of a second) for me. 但是既然你坚持认为,对我来说这是37毫秒(370亿分之一秒)。

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);
}

Result: 结果:

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

Time taken by each deref = 1/3187659 s - 1/3616848 s = 37 ns 每个deref所需的时间= 1/3187659 s - 1/3616848 s = 37 ns

It's tiny! 它很小! Dereferencing the array only accounts for 12% of the time taken to dereference an empty array and copying it into another! 取消引用该数组只占取消引用空数组并将其复制到另一个数组所用时间的12%!

Does the operation first generate a list via split (1) and create an array ref (2), then copy the values of the array ref into a new array when dereferencing (3)? 操作是否首先通过split(1)生成列表并创建数组ref(2),然后在解除引用(3)时将数组ref的值复制到新数组中?

  1. Yes, split returns a list. 是的, split返回一个列表。 Except in scalar context. 标量上下文除外。

  2. [ ... ] doesn't just create a reference, it also creates an array and copies the values into it. [ ... ]不只是创建一个引用,它还创建一个数组并将值复制到其中。

  3. No, dereferencing doesn't copy values. 不,取消引用不会复制值。

Does it morph the current arrayref in place? 它是否将当前的arrayref变形?

It would be really bad if a reference turned into something else. 如果引用变成其他东西,那将是非常糟糕的。 What do you actually mean? 你究竟是什么意思?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM