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

在Perl函数中,引用是否更好地返回值?,perl,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

与返回数组或散列上的引用相比,返回数组或散列的优缺点是什么

对内存或执行时间有影响吗

两者在功能上有什么不同

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

简短回答:这取决于你返回的内容的大小。如果它很小,可以返回整个数组


有关详细信息,请参见堆栈溢出问题。

数组变得更大时,性能影响更为显著,但在perl 5.10上仅为50%左右

我通常更喜欢返回一个引用,因为它使代码更容易阅读:一个函数只有一个返回值,并且避免了一些陷阱(自动标量评估),就像manu_v提到的post引用的那样

#! /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); },
        });
}
返回:

            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%          --

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

是的,这会影响内存和执行时间-返回引用只返回一个(相对较小的)标量,其他什么都不会返回。将数组或散列作为列表返回会生成数组/散列的浅层副本并返回该副本,如果数组/散列较大,则创建副本和存储副本可能会占用大量时间

两者在功能上的区别只是一个问题,即是将结果作为数组/哈希还是作为arrayref/hashref处理。有些人认为引用比工作要麻烦得多;就我个人而言,我不认为这是一个显著的差异。 另一个功能上的区别是,不能将多个数组或散列作为列表返回(它们被展平为单个列表),但可以返回多个引用。当它出现时,它是一个致命的细节迫使你使用引用,但我的经验是它只会很少出现,所以我不知道我认为它是多么重要。 关于标题问题,我认为关于返回列表与引用的最重要因素是,您应该保持一致,这样您就不必浪费时间记住哪些函数返回数组/哈希以及哪些函数返回引用。考虑到引用在某些情况下更好,而且至少对我来说,引用从来不会明显更差,我选择标准化总是将数组/哈希作为引用而不是列表返回


(你也可以选择在你的子系统中使用<代码> WANDORAMORION/CODE >,以便它们在标量上下文中返回列表上下文和引用中的列表,但我倾向于认为这在很大程度上是无意义的过度复杂。)

就接口而言,返回数组可以让您更轻松地处理map和grep之类的内容,而不必求助于

@{bletchoritus}


但是对于散列,返回一个引用通常更有用,因为这样您就可以做一些聪明的事情,比如
my$val=function->{key}
,而不必指定中间变量。

注意,实际上不可能从函数返回数组或散列。函数只能返回标量列表。当您说
return@a
时,您正在返回数组的内容


在某些程序中,返回数组的内容更为简洁。在某些程序中,返回对数组的引用更为简洁。根据具体情况做出决定。

不可能返回数组或哈希。Perl中的函数只能返回一个乏味的列表或标量(取决于函数的上下文)。关于函数返回上下文,这至少是一个有趣的迂腐程度:如果您返回对哈希的引用,而不是返回哈希本身,那么您的哈希示例是有效的。