{
"status": 1,
"error_msg": '',
"result": {
"foo1": { .... },
"foo2": { .... },
"foo3": { .... },
"foo4": { .... }
}
}
After retrieving this, I have to sort the result in result.foo1, result.foo2, ..., result.foo100 order. I'm wondering why they don't return this in array, but I must face it as long as the provider is returning values in this way. Although Perl Best Practicesmy %tmp_cache; # for orcish maneuver
my @sorted_keys = sort {
( $tmp_cache{$a} //= $a =~ s/\A foo(\d+) \z/$1/xr ) <=>
( $tmp_cache{$b} //= $b =~ s/\A foo(\d+) \z/$1/xr )
} keys %{ $content->{result} };
# then sorted results are stored in stash to be displayed
$c->stash->{results} = [ map { $content->{result}->{$_} } @sorted_keys ];
Today, I benchmarked each sort type provided by Sort::Maker and found that using Sort::Maker was much faster. The code is as below. It was a bit surprising that my original method with orcish maneuver is13% slower than Sort::Maker's one with orcish maneuver. Needless to say, other sort types are much faster. So my conclusion is that even relatively simple sort should be implemented with Sort::Maker to increase readability, maintenancibility and performance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use strict; | |
use warnings; | |
use Sort::Maker qw/make_sorter/; | |
use Benchmark qw/:all/; | |
warn "Perl: $]\n"; | |
warn "Sort::Maker: $Sort::Maker::VERSION\n\n"; | |
#Perl: 5.018001 | |
#Sort::Maker: 0.06 | |
# | |
# Rate plain original orcish ST GRT | |
#plain 6.83/s -- -79% -82% -85% -86% | |
#original 33.2/s 386% -- -13% -25% -34% | |
#orcish 38.4/s 462% 16% -- -14% -23% | |
#ST 44.5/s 551% 34% 16% -- -11% | |
#GRT 50.2/s 635% 51% 31% 13% -- | |
my $hashref = +{ | |
status => 1, | |
error_msg => '', | |
result => +{}, | |
}; | |
$hashref->{result}->{ sprintf('foo%d', $_) } = rand(100) for 1..5_000; | |
my $sort_rule = +{ | |
number => +{ | |
code => sub { /\A foo(\d+) \z/xms }, | |
ascending => 1, | |
} | |
}; | |
my $sorter_plain = make_sorter( plain => 1, %$sort_rule ); | |
my $sorter_orc = make_sorter( orcish => 1, %$sort_rule ); | |
my $sorter_st = make_sorter( ST => 1, %$sort_rule ); | |
my $sorter_grt = make_sorter( GRT => 1, %$sort_rule ); | |
my $sorter_orig = sub { | |
my %tmp_cache; | |
sort { | |
( $tmp_cache{$a} //= $a =~ s/\A foo(\d+) \z/$1/xr ) <=> | |
( $tmp_cache{$b} //= $b =~ s/\A foo(\d+) \z/$1/xr ) | |
} @_; | |
}; | |
cmpthese( | |
1_000, | |
+{ | |
plain => sub { | |
my @sorted_keys = $sorter_plain->( keys %{ $hashref->{result} } ); | |
}, | |
orcish => sub { | |
my @sorted_keys = $sorter_orc->( keys %{ $hashref->{result} } ); | |
}, | |
ST => sub { | |
my @sorted_keys = $sorter_st->( keys %{ $hashref->{result} } ); | |
}, | |
GRT => sub { | |
my @sorted_keys = $sorter_grt->( keys %{ $hashref->{result} } ); | |
}, | |
original => sub { | |
my @sorted_keys = $sorter_orig->( keys %{ $hashref->{result} } ); | |
}, | |
}, | |
); | |
__END__ |