Edit: When I posted this, the question asked if the following code would make a copy of the string:
my $x = \" VERY VERY BIG STRING .....";
my $len = length( $$x );
Everything below the <hr> answers that question. The question has since been edited with much more information, which made my initial answer no longer make (much) sense.
my $s = shift; will not, by itself, increase memory usage, at least on recent Perls:
my $string = 'Long string' x 100000;
sub psau() { print grep { /\b$$\b/ } `ps au` } # POSIX platforms
sub bar { psau }
sub foo { my $s = shift; psau }
sub mod { my $s = shift; $s =~ s/Long/LONG/g; psau }
psau;
bar($string);
foo($string);
mod($string);
psau;
On my system, that shows an increase only on the last call which modifies the string, mod($string).
This copy-on-write behavior was introduced in Perl 5.20, so results would differ on older Perls, and some specifics will be platform dependent.
As to whether there is a performance penalty to dereferencing the string, the answer to that is unfortunately yes:
use Benchmark qw<cmpthese>;
my $string = 'Long string' x 1000;
my $really_long = $string x 100;
my $ref = \$string;
my $long_ref = \$really_long;
cmpthese(-5, {
map { $_ => "length($_)" } qw< $string $$ref $really_long $$long_r
+ef >
});
__END__
Rate $$long_ref $$ref $really_long $s
+tring
$$long_ref 17305170/s -- -9% -36%
+ -38%
$$ref 18937129/s 9% -- -30%
+ -32%
$really_long 27185304/s 57% 44% --
+ -2%
$string 27870647/s 61% 47% 3%
+ --
I included two drastically different strings to illustrate the point that Perl does not need to scan the entire string to know the length of the scalar, since the length is part of the internal representation. The performance penalty is for the dereference only.
use strict; use warnings; omitted for brevity.
|