"return @my_array; will create a copy of the array, and this isn't efficient if all you want is just the number of element in the array."

I don't believe it's correct that a copy of @my_array is made when return @my_array is evaluated in scalar context. Perl is smart enough to know about the context from within the subroutine. Context passes through, so to speak. No copy is made, and all that happens is that @my_array happily tells return to tell the lvalue scalar that there are 23 elements (or whatever number).

Here is Yet Another Benchmark. I believe that this gets right down to brass tacks. All that we are comparing is how fast return @array takes place in scalar context, versus return $nonarray, also in scalar context. Thus, we can see if there is extra time being taken to create a copy of @array. I think you'll find the results surprising.

First, the code:

use strict; use warnings; use Benchmark; my @array; push @array, "Test string" for 1..20000; my $nonarray = "Test string"; sub passarray { return @array; } sub passscalar { return $nonarray; } my $count = 500000; timethese ( $count, { "Scalar" => sub { my $test = passscalar() }, "List" => sub { my $test = passarray() } } );

And now for the exciting results...

Benchmark: timing 500000 iterations of List, Scalar... List: 0 wallclock secs ( 0.73 usr + 0.00 sys = 0.73 CPU) @ 6830 +60.11/s (n=500000) Scalar: 2 wallclock secs ( 1.38 usr + 0.00 sys = 1.38 CPU) @ 3617 +94.50/s (n=500000)

Surprised to find that the return @array; subroutine was faster than the return $nonarray;? I was. I figued that they would be about equal. There couldn't possibly be a copying of the array going on; that would take way too long. That part doesn't surprise me. What surprises me is that it's quicker to say, "I have 20,000 elements" than it is to say, "I contain the string, 'Test string'". By the way, the same time differential holds true even if $nonarray contains just a one-character string.

The explanation that I can come up with is pure speculation: When comparing the operation of an array knowing its size, compared to the operation of a scalar knowing its value, the former is a less costly operation.


Dave


"If I had my life to do over again, I'd be a plumber." -- Albert Einstein

In reply to Re: Re: Re: returning arrays from a sub - how clever is Perl? by davido
in thread returning arrays from a sub - how clever is Perl? by mildside

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.