与返回引用相比,返回数组或哈希的优缺点是什么?
是否会影响内存或执行时间?
两者之间的功能差异是什么?
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)
当阵列变大时,性能影响更明显,但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上,数字可能会有所不同.
是的,会对内存和执行时间产生影响 - 返回引用会返回一个(相对较小的)标量,而不会返回任何其他内容.将数组或散列作为列表返回会生成数组/散列的浅表副本并返回该数据,如果数组/散列很大,则可能需要花费大量时间来使副本和内存存储副本.
两者之间的功能差异只是一个问题,即您是将结果作为数组/散列还是作为arrayref/hashref使用.有些人认为引用更加繁琐; 就个人而言,我不认为这是一个重大的区别.
另一个功能区别是您不能将多个数组或哈希值作为列表返回(它们会被展平为单个列表),但您可以返回多个引用.当这出现时,它是一个杀手细节,迫使你使用引用,但我的经验是它只出现很少,所以我不知道我认为它是多么重要的整体.
回到标题问题,我认为关于返回列表与引用的最重要因素是你应该保持一致,这样你就不必浪费时间记住哪些函数返回数组/哈希值以及返回引用.鉴于在某些情况下引用更好,并且至少对我来说,引用从来没有明显更糟,我选择标准化总是返回数组/哈希作为引用而不是列表.
(你也可以选择wantarray在你的潜艇中使用标准化,这样他们就会在列表上下文中返回列表并在标量上下文中引用,但我倾向于认为这是一个毫无意义的过度复杂化.)
就接口而言,返回一个数组可以让你更轻松地使用map和grep之类的东西来处理它而不必诉诸于此@{bletchorousness}.
但是对于哈希,返回引用通常更有用,因为这样你就可以做一些聪明的事情,my $val = function->{key}而不必分配给一个中间变量.