引用是否更好地返回Perl函数中的值?

Als*_*nde 11 perl

与返回引用相比,返回数组或哈希的优缺点是什么?

是否会影响内存或执行时间?

两者之间的功能差异是什么?

sub i_return_an_array
{
    my @a = ();
    # push things in @a;
    return @a;
}

sub i_return_a_ref
{
    my @a = ();
    # push things in @a;
    return \@a;
}

my @v = i_return_an_array();
my $v = i_return_a_ref();
Run Code Online (Sandbox Code Playgroud)

Ste*_*epp 9

阵列变大时,性能影响更明显,但perl 5.10只有50%左右.

我平时喜欢返回一个参考,因为它使代码更易于阅读:一个函数只有一个返回值,并避免一些陷阱(自动标评价)由提到manu_v引用的文章.

#! /usr/bin/perl
use Benchmark;

sub i_return_an_array
{
    my @a = (1 .. shift);
    # push things in @a;
    return @a;
}

sub i_return_a_ref
{
    my @a = (1 .. shift);
    # push things in @a;
    return \@a;
}

for my $nb (1, 10, 100, 1000, 10000) {
        Benchmark::cmpthese(0, {
                "array_$nb" => sub { my @v = i_return_an_array($nb); },
                "ref_$nb" => sub { my $v = i_return_a_ref($nb); },
        });
}
Run Code Online (Sandbox Code Playgroud)

回报:

            Rate   ref_1 array_1
ref_1   702345/s      --     -3%
array_1 722083/s      3%      --
             Rate array_10   ref_10
array_10 230397/s       --     -29%
ref_10   324620/s      41%       --
             Rate array_100   ref_100
array_100 27574/s        --      -47%
ref_100   52130/s       89%        --
             Rate array_1000   ref_1000
array_1000 2891/s         --       -51%
ref_1000   5855/s       103%         --
             Rate array_10000   ref_10000
array_10000 299/s          --        -48%
ref_10000   578/s         93%          --
Run Code Online (Sandbox Code Playgroud)

在其他版本的perl上,数字可能会有所不同.


Dav*_*man 9

是的,会对内存和执行时间产生影响 - 返回引用会返回一个(相对较小的)标量,而不会返回任何其他内容.将数组或散列作为列表返回会生成数组/散列的浅表副本并返回该数据,如果数组/散列很大,则可能需要花费大量时间来使副本和内存存储副本.

两者之间的功能差异只是一个问题,即您是将结果作为数组/散列还是作为arrayref/hashref使用.有些人认为引用更加繁琐; 就个人而言,我不认为这是一个重大的区别.

另一个功能区别是您不能将多个数组或哈希值作为列表返回(它们会被展平为单个列表),但您可以返回多个引用.当这出现时,它是一个杀手细节,迫使你使用引用,但我的经验是它只出现很少,所以我不知道我认为它是多么重要的整体.

回到标题问题,我认为关于返回列表与引用的最重要因素是你应该保持一致,这样你就不必浪费时间记住哪些函数返回数组/哈希值以及返回引用.鉴于在某些情况下引用更好,并且至少对我来说,引用从来没有明显更糟,我选择标准化总是返回数组/哈希作为引用而不是列表.

(你可以选择wantarray在你的潜艇中使用标准化,这样他们就会在列表上下文中返回列表并在标量上下文中引用,但我倾向于认为这是一个毫无意义的过度复杂化.)


Sch*_*ern 5

就接口而言,返回一个数组可以让你更轻松地使用map和grep之类的东西来处理它而不必诉诸于此@{bletchorousness}.

但是对于哈希,返回引用通常更有用,因为这样你就可以做一些聪明的事情,my $val = function->{key}而不必分配给一个中间变量.