返回数组或哈希与返回引用相比有什么优缺点?
是否会对内存或执行时间产生影响?
两者之间有什么功能差异?
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();
答案 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
时,您将返回数组的内容。
在某些程序中,它可以更清晰地返回数组的内容。在某些程序中,它可以更干净地返回对数组的引用。根据具体情况做出决定。