使用eval修饰符返回字符串或字符串引用

时间:2014-12-31 15:44:57

标签: perl

使用e修饰符时,返回对字符串的引用而不是字符串本身是否有任何优势?

例如:

use strict;
use warnings;

my $str1 = my $str2 = "aa bb cc";

$str1 =~ s/\s(bb)\s/${func1($1)}/e;
$str2 =~ s/\s(bb)\s/func2($1)/e;

sub func1 {
    my ($name) = @_;

    my $str = "A large string";
    return \$str;
}

sub func2 {
    my ($name) = @_;

    my $str = "A large string";
    return $str;
}

我正在考虑返回的字符串非常大的情况。使用引用会更有效吗?

1 个答案:

答案 0 :(得分:2)

只有基准测试可以说明,但它看起来像。

返回标量通常会复制它。

$ perl -MDevel::Peek -e'
   sub f { my $x = 'abc'; Dump($x); $x }  Dump(f());
' 2>&1 | grep -Po 'PV = \K\S*'
0x275d5f0
0x276e270

但不是在使用:lvalue时。

$ perl -MDevel::Peek -e'
   sub f :lvalue { my $x = 'abc'; Dump($x); $x }  Dump(f());
' 2>&1 | grep -Po 'PV = \K\S*'
0x220bd00
0x220bd00

5.20引入了写时复制字符串,因此两个标量($x和返回的标量符号)共享相同的字符串缓冲区,直到您更改一个(然后强制复制)。

$ perl -MDevel::Peek -e'
   sub f { my $x = 'abc'; Dump($x); $x }  Dump(f());
' 2>&1 | grep -Po 'PV = \K\S*'
0xda4780
0xda4780