umasuresh has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

Task
I am passing a array as a reference to a subroutine which does some checking and returns a scalar.

Method1:
my $variable = my_subroutine(\@my_array); sub my_subroutine { my $array = shift; # involves dereferencing the array_reference ... return(\$variable); }
I get the expected output. Array dereferencing can be quite expensive and I wanted to refine the code further.

Method2:
I thought that I can gain some speed by passing just the array indices and access the array defined outside the subroutine as a global array. Again, I get the expected result.
my $variable = my_subroutine(\$array_start_idx, \$array_end_idx); sub my_subroutine { my $start_idx = shift; my $end_idx = shift; # involves accessong the global array using the indices passed ... return(\$variable); }
Problem
When I use Devel-NYTProf to profile both methods, passing the whole array as an array reference is much faster than passing the array indices. I was expecting the opposite of this!
I have to emphasize that innards of the subroutine is dereferencing an array reference in the first option and accessing the global array using the array indices passed to the subroutine.
Any insight into this is greatly apppreciated!

Replies are listed 'Best First'.
Re: Pass an array reference or array indices to a subroutine?
by ikegami (Patriarch) on Feb 24, 2011 at 20:54 UTC

    First, you're not passing indexes, you're passing reference to the indexes. That's surely a bug.

    Secondly, apples and oranges. If you need the indexes, why aren't you passing them using "method 1"? If you don't need the indexes, why are you passing them using "method 2"?

      Ikegami,
      Thanks for your suggestion. I am dereferencing the array indices before accessing the global array. May be my question should have been which one of these is faster: dereferencing an array or a scalar.
      Uma
        May be my question should have been which one of these is faster: dereferencing an array or a scalar.

        They're about the same; almost irrelevant in any real program.

        Accessing a lexical is faster than accessing a global, though the speed difference there is also almost always irrelevant.

        May be my question should have been which one of these is faster: dereferencing an array or a scalar.

        There's no difference.

        And that shouldn't be the question at all. There's no point of comparing things that aren't equivalent.

Re: Pass an array reference or array indices to a subroutine?
by JavaFan (Canon) on Feb 24, 2011 at 22:16 UTC
    Your second method creates two variables in the block of the body, your first method creates one. Creating a variable, even when there is some reuse, is more expensive than doing an array dereference. Furthermore, you're passing references to indices - so your method to avoid array dereferencing does two scalar dereferences.

    But I'm curious about your statement Array dereferencing can be quite expensive. What makes you think that? Dereferencing is just following a pointer. Just doing print $foo means you have to follow a couple of pointers just to get the string value. In the grand scheme of things, array dereferencing is just peanuts.

Re: Pass an array reference or array indices to a subroutine?
by GrandFather (Saint) on Feb 24, 2011 at 21:07 UTC

    Does the speed matter? have you profiled code that is running way too slow for practical use and found that dereferencing the array is the issue that will make all the problems go away?

    If the answer to either of the questions above is 'no' then why are you wasting your time and our time optimising this code?

    True laziness is hard work
Re: Pass an array reference or array indices to a subroutine?
by umasuresh (Hermit) on Feb 24, 2011 at 22:41 UTC
    Thank you all for your valuable comments and suggestions. I am beginning to gain some clarity on this topic!
    UPDATE
    I took a deeper look at the Profiler output and the culprit in the Method2 is in fact due to a totally different reason. I was defining the global array inside a while loop instead of defining it outside!