in reply to Passing variables
First of all, for small arrays there is no noticable difference between passing by ref and passing by value. There is no surprise there. But it always amazes me how many experienced programmers insist on passing strings around by reference and so making their code far more difficult to read.
Now suppose you have a large amount of data to pass to a sub, the question you might want to ask first is:
Does Perl pass by array or by reference?
And, as with most things Perl, the answer is Yes!
When you pass something to a sub, it is passed by reference, but as soon as you assign that to a new variable a copy is created and so it looks as though it was passed by value.
Now suppose you take a reference to @_ you have in effect passed by reference in a way that is transparent to the caller.
Why would you want to do this? Well for the very good reason that you don't want to have to create references in the code that calls the subs. It is obvious that using references is more complicated than using straight variables, so if that can be hidden away in the sub it makes the code a lot clearer which is a good thing
Now before I posted this, I wanted to test it. I started with this:
But the writing of the file was concealing the time taken for the array passing, so I just made sure every element of the array was accessed:sub write_array_1{ my $file = shift; my $r_array = \@_; open FILE, ">$file" or die "failed to open $file ($!)"; print FILE @$r_array; close FILE; }
So passing by value is slower (as expected) but why is the explicit passing by reference quicker than the transparent method? It's faster than passing by value so it must be doing what it's supposed to, but not the same as the explicit reference?use strict; use warnings; use Benchmark; sub write_array_1{ my $file = shift; my $r_array = \@_; $_++ foreach @$r_array; } sub write_array_2{ my $file = shift; my $r_array = shift; $_++ foreach @$r_array; } sub write_array_31{ my $file = shift; my @array = @_; $_++ foreach @array; } my @array = ( 1..100000 ); my $filename = 'C:\users\jake\testing\arrayref.dat'; timethese(30, { 'Pass by ref transparently' => sub {write_array_1( $filename . + 1, @array );}, 'Pass by ref explicitly' => sub {write_array_2( $filename . + 2, \@array );}, 'Pass by value' => sub {write_array_3( $filename . + 3, @array );}, }); Benchmark: timing 30 iterations of Pass by ref explicitly, Pass by ref + transparently, Pass by value... Pass by ref explicitly: 2 wallclock secs ( 1.84 usr + 0.00 sys = 1. +84 CPU) @ 16.27/s (n=30) Pass by ref transparently: 3 wallclock secs ( 2.94 usr + 0.00 sys = + 2.94 CPU) @ 10.21/s (n=30) Pass by value: 4 wallclock secs ( 4.42 usr + 0.02 sys = 4.44 CPU) @ + 6.76/s (n=30)
-- iakobski
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Passing variables
by frag (Hermit) on Jun 15, 2001 at 19:39 UTC |