Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: references best practice

by hipowls (Curate)
on Apr 25, 2008 at 11:33 UTC ( #682790=note: print w/ replies, xml ) Need Help??


in reply to references best practice

The first form returns a list, each item of which is copied. The other two forms copy a single scalar, a reference to an array. I would expect that either of these two to have similar performance.

Suspicion, however is no substitute for benchmarking so I ran the following script.

use warnings; use strict; use Benchmark qw(cmpthese); sub prepData1 { my @data = ( map { log $_ } 1 .. 100 ); return @data; } sub runPrep1 { my @result = prepData1(); } sub prepData2 { my $refData = shift; $refData = [ map { log $_ } 1 .. 100 ]; } sub runPrep2 { my @result; prepData2( \@result ); } sub prepData3 { my @data = ( map { log $_ } 1 .. 100 ); return \@data; } sub runPrep3 { my $result = prepData3(); } sub prepData4 { my $data = [ map { log $_ } 1 .. 100 ]; return $data; } sub runPrep4 { my $result = prepData4(); } cmpthese( -5, # Run each function for at least 5 seconds { array_out => \&runPrep1, array_ref_in => \&runPrep2, array_ref_out1 => \&runPrep3, array_ref_out2 => \&runPrep4, } ); __END__ Rate array_out array_ref_out1 array_ref_in arra +y_ref_out2 array_out 11270/s -- -30% -43% + -44% array_ref_out1 16137/s 43% -- -19% + -20% array_ref_in 19873/s 76% 23% -- + -1% array_ref_out2 20101/s 78% 25% 1% + --
I added a fourth style since that is the form I prefer where the data is directly put in an array reference. Once again benchmarking proves me wrong;-) That's why I always do it rather than guess.

Update 1: I prefer my idiom because I create a single container of related values but I can't pass that back since the function returns a list of values. To retain the relationship between them I use an array reference so that the caller of the function gets back a group of related values. If, for some reason, I need to extend the function to return a second group of data I can pass back two references thereby maintaining the logical grouping of data.

Update 2: As Haarg kindly pointed out I got the second case wrong, I was creating a new anonymous array reference and assigning it to the array ref that was passed int. Updating the code & benchmarks I get

sub prepData2 { my $refData = shift; @$refData = ( map { log $_ } 1 .. 100 ); } __END__ Rate array_out array_ref_out1 array_ref_in arra +y_ref_out2 array_out 11801/s -- -28% -28% + -39% array_ref_out1 16406/s 39% -- -1% + -15% array_ref_in 16496/s 40% 1% -- + -14% array_ref_out2 19238/s 63% 17% 17% + --
Looks my original guess was correct which just shows if benchmarking gives an unexpected result you should check both your assumptions and your benchmarking.


Comment on Re: references best practice
Select or Download Code
Re^2: references best practice
by amarquis (Curate) on Apr 25, 2008 at 18:47 UTC

    Benchmarking doesn't prove you wrong, it proves that something might be slower in a given case.

    If I had to choose between a marginal speed increase an an idiom I am comfortable with, I'd say the latter is correct. (Until I have proof that speed is a problem and profiling tells me this is the bottleneck).

Re^2: references best practice
by Haarg (Chaplain) on Apr 25, 2008 at 22:51 UTC
    Your second example isn't doing what you intend. The array outside of the sub isn't modified. The first line of prepData2 sets $refData to the incoming reference. The second replaces that reference with a different one, leaving the contents of the first reference unchanged. You'd want something more like:
    sub prepData2 { my $refData = shift; @$refData = map { log $_ } 1 .. 100; }
    With that change, the benchmark changes somewhat, making it almost identical to array_ref_out1 in my tests.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://682790]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2015-07-05 18:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (67 votes), past polls