On 4/10/06, Adam W <[EMAIL PROTECTED]> wrote: > Hello List, > > I was wondering when it is appropriate to do multiple shifts on > parameters passed to a subroutine and when it is appropriate to just > feed it @_. > > For example, you have: > > &fancy_sub($a, $b, $c, @d); > > Is it better (I'm leaving this term vague on purpose) to write: > > sub fancy_sub { > my($a, $b, $c, @d) = @_; > ...do some fancy stuff... > } > > or > > sub fancy_sub { > my $a = shift; > my $b = shift; > my $c = shift; > my @d = @_; > ...do some fancy stuff... > } > > Obviously the latter requires more typing, but is there any kind of > optimization for choosing to write it this way? > > Thanks, > Adam
It really depends on your working definition of efficiency. The answer to what is objectively faster lays buried deep in perls internals, and may depend on your OS and C compiler. If shift is able, knowing that that @_ no longer needs the pointer referenced by @_[0] to simply redirect the pointer to the new variable, it'll be marginally faster. If it has to copy and then resize the array, it'll be marginally slower. And the margin will be probably be completely undedectable in normal operation; maybe a few nanoseconds in a few thousand operations, certainly smaller than the margin of error in whatever benchamrking tool you're using for any reasonably-sized data set. What is most efficient for you will depend on what makes sense for a given situation, and what you're doing with yur data. ($str1, $str2, $str3, @array) = @_; leaves @_ intact. You now have two complete copies of the same data resident in memory. For large data sets relative to your available memory, this may be a performance issue. On the other hand, you may want the original values passed in for something. Maybe you want to return the passed in values if a certain condition is met, and modified values otherwise. Maybe you want to do something with both the original values and some modified values. Or maybe.... You get the point. ($str1, $str2, $str3) = (shift, shift, shift); @d = [EMAIL PROTECTED]; On the other hand resizes @_. Now you only have one copy of each value in memory. For a large list, this may be important. the combination of shift, unshift, push and pop also lets you operate on @_ as a stack, FIFO, LIFO, or both. On the other hand, if you modify a value, the original value is destroyed. The different idioms exist to let you approach your data in different ways. Shifting and copying produce very different results, and the monkeying you'll have to do get one idiom to reproduce the behavior of the other will more than offset whatever miniscule performance gains you might get, both in development time and in run time. Lets assume, for the moment, that shifting is faster than copying. What, though would be the use of this? $str1 =shift; $constant = $str1; Conversely, let's assume that that copying is faster. Would you really gain anythnig from: ($str1, $str2, @data) = @_; # and then leave @_ hanging around but never use it Probably not, especialy if @_ is large. Just use whichever technique makes the most sense for a given situation and don't sweat the internals. HTH, -- jay -------------------------------------------------- This email and attachment(s): [ ] blogable; [ x ] ask first; [ ] private and confidential daggerquill [at] gmail [dot] com http://www.tuaw.com http://www.dpguru.com http://www.engatiki.org values of β will give rise to dom!