http://www.perlmonks.org?node_id=927820


in reply to Re: Way to do a "scalar ref"?
in thread Way to do a "scalar ref"?

Hi,

Thanks for the reply. Ok, I'm working on a wiki (which can have VERY large articles in). The site also gets a lot of traffic (several million hits a month), so I need to make this code as optimized as possible. Now, lets say we have:
sub process_article { my $article = get_article_from_db($article_id); my $contents = process_article($article->{contents}); # now I need to access $article->{contents}, but the modified vers +ion from process_article } sub process_article { my $article_contents = $_[0]; # do some stuff to $article_contents here return $article_contents; }
..so basically I wanna be able to pass along $article_contents to different functions, but not actually have it take up more memory (or require a "return", to assign it to a new variable).

Does that make more sense?

TIA

Andy

Replies are listed 'Best First'.
Re^3: Way to do a "scalar ref"?
by moritz (Cardinal) on Sep 26, 2011 at 09:02 UTC
    FWIW @_ and thus $_[0] are already aliases to the variable used in the call, so if you do something like
    sub f { $_[0] =~ s/a/b/g } my $text = 'foo bar' f $text

    No copying happens.

    If you want explicit references, do it like this:

    sub f { my $ref = shift; $$ref =~ s/a/b/g } my $text = 'foo bar' f \$text
    m working on a wiki (which can have VERY large articles in). The site also gets a lot of traffic (several million hits a month), so I need to make this code as optimized as possible.

    Then be sure to read perlperf, and cache wherever possible. If you cache the rendered version of very large articles, the number of renderings becomes proportional to the number of writes, which is usually much lower than the number or reads.

Re^3: Way to do a "scalar ref"?
by johngg (Canon) on Sep 26, 2011 at 09:13 UTC

    You seem to have two process_article subroutines, should we assume the second ought to be called process_article_contents? Perhaps you could pass a reference to the hash value, something like this.

    knoppix@Microknoppix:~$ perl -MData::Dumper -E ' > sub double { $rsVal = shift; $$rsVal *= 2 } > > $rhData = { one => 1, two => 2 }; > say Data::Dumper->Dumpxs( [ $rhData ], [ qw{ rhData } ] ); > > double( \ $rhData->{ two } ); > say Data::Dumper->Dumpxs( [ $rhData ], [ qw{ rhData } ] );' $rhData = { 'one' => 1, 'two' => 2 }; $rhData = { 'one' => 1, 'two' => 4 }; knoppix@Microknoppix:~$

    I hope this is helpful.

    Cheers,

    JohnGG

Re^3: Way to do a "scalar ref"?
by AnomalousMonk (Archbishop) on Sep 26, 2011 at 18:45 UTC

    You can even save one more large, expensive copy operation by returning a reference to the scalar 'content' in the first place rather than the actual content (if you have editorial control over these functions) and just pass around the scalar reference thereafter. In the example below, the only copy performed is the absolutely necessary one (if you do not want to change the original content) associated with the first processing operation. (Update: Of course, you still have to come to terms with all the copying that goes on in all those  s/// operations, which may make the higher-level question moot.)

    >perl -wMstrict -le "my $article = { content => 'FEE FIE FOE FUM' }; ;; print qq{'$article->{content}'}; my $sr = process_content($article); print qq{'$$sr'}; process_content_some_more($sr); print qq{'$$sr'}; ;; sub process_content { my ($hashref) = @_; (my $processed = $hashref->{content}) =~ s{(\w+)}{\L$1}xmsg; return \$processed; } ;; sub process_content_some_more { my ($scalarref) = @_; $$scalarref =~ s{(\w+)}{\u$1}xmsg; } " 'FEE FIE FOE FUM' 'fee fie foe fum' 'Fee Fie Foe Fum'