Here's another question borne out of idle curiosity: what is the most efficient way to force a list context? I used to think that it'd be assigning to the empty list, but that's not the case, at least not always, as the results below show.
First, here's the set-up:
Two sets of benchmarks, corresponding to various ways of forcing list contexts on calls to two different functions: Perl's built-in lexicographic sort function (these are the s_* items), and gr, a simple implementation of a Guttman-Rosler sort (this is basically the subroutine guttros posted by friedo here; these are the g_* items). (The results will show that either set of benchmarks would have been sufficient illustration, but it's nice to have the extra datapoint by way of crosscheck.)use Benchmark 'cmpthese'; sub gr { # Guttman-Rosler transform map { substr( $_, 3 ) } sort map { sprintf( '%03d', /abc(\d+)xyz/ ) . $_ } @_; } srand 0; my @u = map 'abc' . int( rand 1000 ) . 'xyz', 1..500; cmpthese( -1, { s_aa => sub { my @s = sort @u }, s_fi => sub { ( sort @u )[ 0 ] }, s_na => sub { () = sort @u } } ); cmpthese( -1, { g_aa => sub { my @s = gr @u }, g_fi => sub { ( gr @u )[ 0 ] }, g_na => sub { () = gr @u } } );
And here are the results:
There you have it: fetching the first element unequivocally beats assigning to (). I find this very surprising. After all, fetching the first element requires some honest work, but assigning to a null list is something so nominal that I would have expected it to be pretty much the list counterpart of scalar.Rate s_aa s_na s_fi s_aa 1037/s -- -49% -49% s_na 2017/s 95% -- -1% s_fi 2036/s 96% 1% -- Rate g_na g_aa g_fi g_na 237/s -- 0% -14% g_aa 237/s 0% -- -14% g_fi 275/s 16% 16% --
The approaches above are what I could think of as likely candidates for the lowest-overhead list-forcing method. But the results tell me that my intuition on these matters is a poor guide. Are there more efficient methods?
More to the point, why isn't there a direct way to just tell perl we want a list context, just like we can do with scalar context? It's silly to have trick perl into it.
the lowliest monk
In reply to What's most efficient way to get list context? by tlm
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |