I've searched other many Stack questions on map however this requirement is particular and well try as I might I cannot quite get the solution I am looking for, or I think that does exist.
This question is simply about performance.
As limited, background, this code segment used in decoding incoming tokens so it's used on every web request and therefore the performance is critical and I know "map" can be used so want to use it.
Here is a trimmed down but nevertheless fully working code segment which I am currently using and works perfectly well:
use strict;
use Data::Dumper qw (Dumper);
my $api_token = { array => [ 'user_id', 'session_id', 'expiry' ], max => 3, name => 'session' };
my $token_got = [ 9923232345812112323, 1111323232000000465, 1002323001752323232 ];
my $rt;
for (my $i=0; $i<scalar @{$api_token->{array}}; $i++) {
$rt->{$api_token->{array}->[$i]} = $token_got->[$i];
}
$rt->{type} = $api_token->{name};
print Dumper ($rt) . "\n";
The question is: What is the absolute BEST POSSIBLE PERL CODE to replicate the foreach statement above in terms of performance?
Looks like you only need a hash slice
my %rt;
@rt{ @{ $api_token->{array} } } = @$token_got;
Or, if the hash reference is needed
my $rt;
@{ $rt } { @{ $api_token->{array} } } = @$token_got;
or with the newer postfix dereferencing, on both array and hash slices, perhaps a bit nicer
my $rt;
$rt->@{ $api_token->{array}->@* } = @$token_got;
One can also do it using List::MoreUtils::mesh, and in one statement
my $rt = { mesh @{ $api_token->{array} }, @$token_got };
or with pairwise from the same library
my $rt = { pairwise { $a, $b } @{ $api_token->{array} }, @$token_got };
These go via C code if the library gets installed with List::MoreUtils::XS
.
Benchmarked all above, with the tiny datasets from the question (realistic though?), and whatever implementation mesh
/pairwise
have they are multiple times as slow as the others.
On an old laptop with v5.26
Rate use_pair use_mesh use_href use_post use_hash use_pair 373639/s -- -36% -67% -67% -68% use_mesh 580214/s 55% -- -49% -49% -51% use_href 1129422/s 202% 95% -- -1% -5% use_post 1140634/s 205% 97% 1% -- -4% use_hash 1184835/s 217% 104% 5% 4% --
On a server with v5.36 the numbers are around 160%--170%
against pairwise
(with mesh
being a bit faster than it, similarly to above)
Of the others, on the laptop the hash-based one is always a few percent quicker, while on a server with v5.36 they are all very close. Easy to call it a tie.
The following is edit by OP, who timed a 61% speedup (see comments)
CHANGED CODE:
@rt{ @{ $api_token->{array} } } = @$token_got; ### much faster onliner replaced the loop. @zdim credit