2011-03-15 59 views
10

返回一个数组或哈希与使用它返回引用相比,有什么优点和缺点?在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(); 
+2

无法返回数组或哈希。 Perl中的函数只能返回一个列表或一个标量(取决于函数的上下文) – tadmc 2011-03-16 02:44:47

+1

这是无趣的迂腐。这至少是迂腐约函数返回上下文一个有趣的级别:http://search.cpan.org/perldoc?Want – Schwern 2011-03-19 15:23:03

回答

8

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

两者之间的功能差异仅仅是您是否将结果作为数组/散列或作为arrayref/hashref使用的问题。有些人认为参考工作更麻烦;我个人认为这不是一个重大的区别。

另一个功能区别是你不能返回多个数组或散列作为列表(它们被拼合成一个列表),但是你可以返回多个引用。当出现这种情况时,这是一个迫使你使用引用的杀手级的细节,但是我的经验是,它只是很少出现,所以我不知道我认为它的整体性有多重要。

回到标题问题,我认为关于返回列表与引用最重要的因素是您应该保持一致,以便您不必浪费时间记住哪些函数返回数组/散列,哪些函数返回引用。鉴于引用在某些情况下更好,至少对我而言,引用永远不会更糟,我选择标准化总是将数组/散列作为引用而不是列表。

(您可以也可以选择使用你的潜艇wantarray规范,这样他们就会在标量上下文返回列表上下文,并列出参考文献,但我倾向于认为这是过于复杂在很大程度上没有意义的。)

8

对性能的影响是比较明显的阵列越来越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,数据可能会有所不同。

5

至于接口方面,返回一个数组,您可以处理它的东西像地图和grep更容易,而不必诉诸@{bletchorousness}

但是对于哈希函数,返回引用通常更有用,因为这样您就可以执行诸如my $val = function->{key}之类的巧妙操作,而无需分配给中间变量。

+0

你的散列例如工作,如果你返回一个参考散列,而不是如果回到哈希本身。 – RickF 2011-03-17 13:11:26

+0

哎呀,意思是说参考。 – Schwern 2011-03-19 15:20:45

1

请注意,这是不能够实际从函数返回一个数组或哈希。函数可以返回的唯一东西是标量列表。当你说return @a时,你正在返回数组的内容。

在某些程序,它的作品了更干净返回数组的内容。在某些程序中,它会更干净地返回对数组的引用。根据情况做出决定。