#!/usr/bin/perl use strict; use warnings; use Benchmark qw /timethese cmpthese/; our @advocates = map {{fld_title => 'Rec' . $_, fld_type => [qw /National State Local/] -> [rand 3]}} 1 .. shift || 1000; sub by_locale { my $a_type; my $b_type; $a_type = 1 if ($a->{'fld_type'} =~ /local/i); $a_type = 2 if ($a->{'fld_type'} =~ /state/i); $a_type = 3 if ($a->{'fld_type'} =~ /national/i); $b_type = 1 if ($b->{'fld_type'} =~ /local/i); $b_type = 2 if ($b->{'fld_type'} =~ /state/i); $b_type = 3 if ($b->{'fld_type'} =~ /national/i); $a_type <=> $b_type; } my $order = "\0local\0state\0national\0"; sub by_locale_b { index ($order, "\0" . lc ($a -> {fld_type}) . "\0") <=> index ($order, "\0" . lc ($b -> {fld_type}) . "\0") } our (@knowmad, @abigail, @borisz, @pirate); cmpthese -1 => { knowmad => '@knowmad = sort by_locale @advocates', abigail => 'my %bucket; map {push @{$bucket {$_ -> {fld_type}}} => $_} @advocates; @abigail = map {@{$bucket {$_}}} qw /Local State National/;', borisz => 'my %h = (National => 3, State => 2, Local => 1); @borisz = sort {$h {$a -> {fld_type}} <=> $h {$b -> {fld_type}}} @advocates;', pirate => '@pirate = map {$_ -> [1]} sort {$a -> [0] <=> $b -> [0]} map {[lc ($_ -> {fld_type}), $_]} @advocates', browseruk => '@browseruk = sort by_locale_b @advocates', }; __END__ Rate knowmad browseruk borisz pirate abigail knowmad 39.4/s -- -48% -70% -83% -92% browseruk 75.5/s 91% -- -42% -67% -85% borisz 130/s 229% 72% -- -43% -74% pirate 229/s 480% 203% 76% -- -53% abigail 491/s 1147% 551% 279% 115% --