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.


There is no size penalty, aside from the insignificant size of the reference itself:

use Devel::Size qw< size total_size >; sub size_print($\$) { my ($name, $ref) = @_; printf "%20s %5d %5d\n", $name, size($ref), total_size($ref); } my $string = 'Long string' x 100; printf "%20s %5s %s\n", qw<Name size total_size>; size_print '$string', $string; my $collection = [ ]; size_print '$collection (empty)', $collection; push @$collection, \$string; size_print '$collection ( one )', $collection; push @$collection, \$string; size_print '$collection ( two )', $collection; __END__ Name size total_size $string 1134 1134 $collection (empty) 24 88 $collection ( one ) 24 1278 $collection ( two ) 24 1302

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.

In reply to Re: scalar reference and length by rjt
in thread scalar reference and length by coyocanid

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.