I've been working on an infrastructure module that needs to be as fast as possible. As I don't have the time to trudge the XS learning curve, I've been working on speeding the Perl up.

One of the things I found when examining usage is that there's an awful lot of the following:

sub foo { ..... return @foo; } my $num_foo = foo( @args );

So, I was thinking - would using wantarray be faster than not? Or, alternately, does Perl implicitly use wantarray for you? Out comes Benchmark!

Using 5.8.0 on Solaris9 ...

my @x = 1 .. 1_000_000; sub want { return wantarray ? @x : $#x + 1; } sub nowant { return @x; } cmpthese( -10, { '1nowant' => sub { my $x = nowant(); }, '2want' => sub { my $x = want(); }, '3nowant_list' => sub { my $x = () = nowant(); }, '4want_list' => sub { my $x = () = want(); }, }); -------- Benchmark: running 1nowant, 2want, 3nowant_list, 4want_list for at lea +st 10 CPU seconds... 1nowant: 10 wallclock secs (10.25 usr + 0.00 sys = 10.25 CPU) @ 58 +2570.73/s (n=5971350) 2want: 10 wallclock secs (10.05 usr + 0.00 sys = 10.05 CPU) @ 57 +8237.81/s (n=5811290) 3nowant_list: 11 wallclock secs (10.84 usr + 0.00 sys = 10.84 CPU) @ + 1.11/s (n=12) 4want_list: 11 wallclock secs (10.66 usr + 0.00 sys = 10.66 CPU) @ 1 +.13/s (n=12) Rate 3nowant_list 4want_list 2want 1now +ant 3nowant_list 1.11/s -- -2% -100% -1 +00% 4want_list 1.13/s 2% -- -100% -1 +00% 2want 578238/s 52234049% 51366692% -- +-1% 1nowant 582571/s 52625456% 51751600% 1% + --

The results seem to say that Perl puts a wantarray in for you, if it seems appropriate. What looks to be proof to me is that if you force list context, but still assign to a scalar, you lose a ton of speed. In fact, wantarray seems to be slightly slower. (It actually isn't, if you reverse the order of running. Plus, my personal rule of thumb is that anything which doesn't provide 5% or more of difference is a wash.)

So, it seems that this micro-optimization actually doesn't help.

Update: Fixed the code and re-ran it. The values changed a bit.

Benchmark: running 1nowant, 2want, 3nowant_list, 4want_list for at lea +st 10 CPU seconds... 1nowant: 13 wallclock secs (10.67 usr + 0.00 sys = 10.67 CPU) @ 55 +8715.46/s (n=5961494) 2want: 12 wallclock secs (10.66 usr + 0.00 sys = 10.66 CPU) @ 39 +0887.71/s (n=4166863) 3nowant_list: 11 wallclock secs (10.75 usr + 0.00 sys = 10.75 CPU) @ + 1.12/s (n=12) 4want_list: 11 wallclock secs (10.72 usr + 0.00 sys = 10.72 CPU) @ 1 +.12/s (n=12) Rate 3nowant_list 4want_list 2want 1now +ant 3nowant_list 1.12/s -- -0% -100% -1 +00% 4want_list 1.12/s 0% -- -100% -1 +00% 2want 390888/s 35016924% 34919202% -- - +30% 1nowant 558715/s 50051494% 49911815% 43% + --

Using wantarray actually seems to be a penalty, not an improvement.

------
We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

I shouldn't have to say this, but any code, unless otherwise stated, is untested

Replies are listed 'Best First'.
•Re: Optimizing with wantarray
by merlyn (Sage) on Aug 05, 2004 at 20:15 UTC
    I think you're misinterpreting the semantics and therefore the results.

    If you call a subroutine in a scalar context, that context gets propogated to the expression that is calculating the return value automatically. Likewise, a list context. This is documented, and is not an "optimization", but a definition!

    Remember, it's not just about list vs length of list... see my On Scalar Context for all the ways that this introduced context can affect the result.

    Thus, a subroutine called in a scalar context could never have constructed any sort of list at any time during the return. It has to construct a scalar of the appropriate flavor. And for @foo, that's gonna be the length of the foo array, and none other.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      So, this would basically be the difference between the LHS and RHS of the assignment?

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested

        I'm not sure what you mean.

        The LHS of an assignment determines whether the assignment is a scalar assignment or a list assignment, which are entirely separate operations even though they are both spelled with "=".

        And based on the type of assignment operation, the RHS is evaluated in a list context or a scalar context.

        That's the way it works. Now if you could explain your question in terms of that, I'd be happy to answer. {grin}

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: Optimizing with wantarray
by gmpassos (Priest) on Aug 06, 2004 at 06:54 UTC
    Hey, you wrote want_array in your code! Should be wantarray.

    Graciliano M. P.
    "Creativity is the expression of the liberty".