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!

Reply via email to