For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > November 2005 > Is passing by reference preferrable?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Is passing by reference preferrable?
Markus Dehmann

2005-11-27, 6:58 pm

Is it preferrable to pass variables by reference, or does the perl
interpreter optimize things so that it's not necessary?

In other words, is the 2nd variant of the following two much more efficient?

$a = "bla";
$a = modify($a);
print $a;
sub modify { my $b = shift; $b =~ s/l/L/; return $b; }

$a = "bla";
modify(\$a);
print $a;
sub modify { my $bRef = shift; $$bRef =~ s/l/L/; }


Thanks!
Markus
Bob Walton

2005-11-27, 6:58 pm

Markus Dehmann wrote:

> Is it preferrable to pass variables by reference, or does the perl
> interpreter optimize things so that it's not necessary?


Preferable? Preferable for what? Clarity? Speed? Obfuscation?

If you want to know about speed,

use Benchmark;

and find out. It might be different on your platform and Perl
version than on others.

Both schemes have their uses, advantages and divantages.
Arrays and hashes are generally best passed by reference if there
is more than one argument to the sub, or if the array or hash is
large. You can read up on it in:

perldoc perlsub
....
> Markus

--
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl
xhoster@gmail.com

2005-11-27, 6:58 pm

Markus Dehmann <markus.dehmann@gmail.com> wrote:
> Is it preferrable to pass variables by reference, or does the perl
> interpreter optimize things so that it's not necessary?


Whether it is preferrable rarely has anything to do with how the
interpreter optimizes things. Preferred code is usually determined more by
things like correctness, intuitiveness, maintainibility, etc.

Micro-optimiztion of your code is extremely context and detail dependent,
so it is hard to make general statements.

>
> In other words, is the 2nd variant of the following two much more
> efficient?
>
> $a = "bla";
> $a = modify($a);
> print $a;
> sub modify { my $b = shift; $b =~ s/l/L/; return $b; }
>
> $a = "bla";
> modify(\$a);
> print $a;
> sub modify { my $bRef = shift; $$bRef =~ s/l/L/; }


time perl -le 'foreach(1..1e7) {$a = "bla";$a = modify($a)}; \
sub modify { my $b = shift; $b =~ s/l/L/; return $b; }'
22.640u 0.000s 0:23.24 97.4% 0+0k 0+0io 351pf+0w

time perl -le 'foreach(1..1e7) {$a = "bla";modify(\$a)}; \
sub modify { my $bRef = shift; $$bRef =~ s/l/L/; }'
16.430u 0.000s 0:17.26 95.1% 0+0k 0+0io 352pf+0w

I'd say it is slightly more efficient, not much more efficient. (Of
course, if $a was much larger, this difference could become greater. But
then again, if $a was much larger, just creating $a in the first place
would probably swamp your call involving $a.)

BTW, did you know that perl automatically passes scalars by alias (which
is kind of, but not exactly, like passing by reference) and that if you
wish to avoid copying the way to do it is by not copying elements of @_ in
the first place? (both you're "my $b = shift" and "my $bRef = shift" are
examples of such copying.)

time perl -le 'foreach(1..1e7) {$a = "bla";modify($a)}; \
sub modify { $_[0] =~ s/l/L/; }'
11.520u 0.010s 0:11.60 99.3% 0+0k 0+0io 349pf+0w

But again, micro-optimization of obviously toy code is rarely of much
value.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Tad McClellan

2005-11-27, 6:58 pm

Markus Dehmann <markus.dehmann@gmail.com> wrote:

> In other words, is the 2nd variant of the following two much more efficient?



perldoc Benchmark


> $a = "bla";
> $a = modify($a);
> print $a;
> sub modify { my $b = shift; $b =~ s/l/L/; return $b; }
>
> $a = "bla";
> modify(\$a);
> print $a;
> sub modify { my $bRef = shift; $$bRef =~ s/l/L/; }



There is also a 3rd alternative to consider:

$a = "bla";
modify($a);
print $a;
sub modify { $_[0] =~ s/l/L/; }


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
Markus Dehmann

2005-11-27, 6:58 pm

xhoster@gmail.com wrote:
> Markus Dehmann <markus.dehmann@gmail.com> wrote:
>
>
>
> Whether it is preferrable rarely has anything to do with how the
> interpreter optimizes things. Preferred code is usually determined more by
> things like correctness, intuitiveness, maintainibility, etc.
>
> Micro-optimiztion of your code is extremely context and detail dependent,
> so it is hard to make general statements.
>
>
>
>
> time perl -le 'foreach(1..1e7) {$a = "bla";$a = modify($a)}; \
> sub modify { my $b = shift; $b =~ s/l/L/; return $b; }'
> 22.640u 0.000s 0:23.24 97.4% 0+0k 0+0io 351pf+0w
>
> time perl -le 'foreach(1..1e7) {$a = "bla";modify(\$a)}; \
> sub modify { my $bRef = shift; $$bRef =~ s/l/L/; }'
> 16.430u 0.000s 0:17.26 95.1% 0+0k 0+0io 352pf+0w
>
> I'd say it is slightly more efficient, not much more efficient. (Of
> course, if $a was much larger, this difference could become greater. But
> then again, if $a was much larger, just creating $a in the first place
> would probably swamp your call involving $a.)
>
> BTW, did you know that perl automatically passes scalars by alias (which
> is kind of, but not exactly, like passing by reference) and that if you
> wish to avoid copying the way to do it is by not copying elements of @_ in
> the first place? (both you're "my $b = shift" and "my $bRef = shift" are
> examples of such copying.)
>
> time perl -le 'foreach(1..1e7) {$a = "bla";modify($a)}; \
> sub modify { $_[0] =~ s/l/L/; }'
> 11.520u 0.010s 0:11.60 99.3% 0+0k 0+0io 349pf+0w


It's interesting that if you don't copy and just use $_[0], as you
suggest, then passing by reference is not an advantage anymore. It even
seems passing by reference is slower than passing by value now:

time perl -le 'foreach(1..1e7) {$a = "bla";modify($a)}; \
sub modify {$_[0] =~ s/l/L/; }'
10.494u 0.018s 0:10.54 99.6% 0+0k 0+0io 27pf+0w
time perl -le 'foreach(1..1e7) {$a = "bla";modify(\$a)}; \
sub modify { ${$_[0]} =~ s/l/L/; }'
12.976u 0.014s 0:13.05 99.4% 0+0k 0+0io 0pf+0w

But then, time is rather unreliable of course, and the Benchmark module
should be used here...

Markus
xhoster@gmail.com

2005-11-27, 6:58 pm

Markus Dehmann <markus.dehmann@gmail.com> wrote:
> xhoster@gmail.com wrote:
>
> time perl -le 'foreach(1..1e7) {$a = "bla";modify($a)}; \
> sub modify {$_[0] =~ s/l/L/; }'
> 10.494u 0.018s 0:10.54 99.6% 0+0k 0+0io 27pf+0w
> time perl -le 'foreach(1..1e7) {$a = "bla";modify(\$a)}; \
> sub modify { ${$_[0]} =~ s/l/L/; }'
> 12.976u 0.014s 0:13.05 99.4% 0+0k 0+0io 0pf+0w
>
> But then, time is rather unreliable of course, and the Benchmark module
> should be used here...



How so? I find "time" to be at least as reliable as Benchmark.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Eric J. Roode

2005-11-27, 9:56 pm

Markus Dehmann <markus.dehmann@gmail.com> wrote in
news:3uu7ulF13a44kU1@individual.net:

> Is it preferrable to pass variables by reference, or does the perl
> interpreter optimize things so that it's not necessary?
>
> In other words, is the 2nd variant of the following two much more
> efficient?
>
> $a = "bla";
> $a = modify($a);
> print $a;
> sub modify { my $b = shift; $b =~ s/l/L/; return $b; }
>
> $a = "bla";
> modify(\$a);
> print $a;
> sub modify { my $bRef = shift; $$bRef =~ s/l/L/; }


In perl, *everything* is passed by reference.

$a = 'bla';
modify ($a);
print $a;
sub modify { $_[0] =~ s/l/L/ }

--
Eric
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
brian d foy

2005-11-27, 9:56 pm

In article <3uubk9F12r8bpU1@individual.net>, Markus Dehmann
<markus.dehmann@gmail.com> wrote:

> But then, time is rather unreliable of course, and the Benchmark module
> should be used here...


Actually, time(1) tends to be more reliable. A lot of numbers that
come out of Benchmark don't add up (literally) because there is
about a 7% error from the null-loop handling. The precision of
Benchmark.pm tends to be pretty low.

--
brian d foy, bdfoy@cpan.org
Subscribe to The Perl Review: http://www.theperlreview.com
Ingo Menger

2005-11-28, 7:56 am


Markus Dehmann schrieb:

> xhoster@gmail.com wrote:


[color=darkred]
> It's interesting that if you don't copy and just use $_[0], as you
> suggest, then passing by reference is not an advantage anymore. It even
> seems passing by reference is slower than passing by value now:


At the contrary, it would be "interesting" if this were not so.

As xhoster explained, the value is passed by (kind a) reference anyway,
so taking an extra reference and dereferencing it in the subroutine
requires so much extra CPU cycles.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com