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

时间:2011-03-15 09:14:28

标签: 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();

5 个答案:

答案 0 :(得分: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); },
        });
}

返回:

            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上,数字可能会有所不同。

答案 1 :(得分:9)

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

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

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

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

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

答案 2 :(得分:5)

就接口而言,返回数组允许您使用map和grep等方法更轻松地处理它,而不必诉诸@{bletchorousness}

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

答案 3 :(得分:2)

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

有关详情,请参阅Stack Overflow问题 Is returning a whole array from a Perl subroutine inefficient?

答案 4 :(得分:1)

请注意,实际上不可能从函数返回数组或散列。函数唯一可以返回的是标量列表。当您说return @a时,您将返回数组的内容。

在某些程序中,它可以更清晰地返回数组的内容。在某些程序中,它可以更干净地返回对数组的引用。根据具体情况做出决定。