use strict; use warnings; my @array=qw(a b c d e); my $num = 13; sub jw { my $average = int($num/@array); my %result = map{$_=>$average} @array; for my $i (1..($num - $average*@array)){ ++$result{$array[$i-1]}; } %result } sub ike1 { my %result; my $n=$num; $result{$array[$n%@array]}++ while ($n--); %result } sub ike1b { my %result; $result{$array[$_%@array]}++ for (1..$num); %result } sub ike3 { my $i; map{$array[$i++],length}('1'x$num)=~/^@{['(.*)'.'(\1.?)'x$#array]}$/ } sub zaxo { my %result; @result{@array} = map { int($num/@array) + ($_ < $num % @array) } 0 .. $#array; %result } sub davido { my %result; my @a=@array; my $n=$num; $result{do{my$v=shift@a;push@a,$v;$v}}++while$n--; %result } sub ted { my %result; my $n=0; $result{$array[$n++]} = int($num / ($#array + 1)) + ($num % ($#array + 1) > $n) while ($n <= $#array); %result } sub pela { my %result; foreach (1..$num) { $result{$array[int(rand(scalar(@array)))]}++; } $result{$_} ||= 0 foreach (@array); %result } use Benchmark (); Benchmark::cmpthese(0, { jw => \&jw, ike1 => \&ike1, ike3 => \&ike3, ike1b => \&ike1b, zaxo => \&zaxo, davido => \&davido, ted => \&ted, pela => \&pela, }); __END__ #### Rate davido ike3 pela jw ted ike1b zaxo ike1 davido 22603/s -- -50% -54% -66% -69% -70% -73% -73% ike3 45636/s 102% -- -8% -31% -37% -40% -45% -45% pela 49364/s 118% 8% -- -25% -32% -35% -40% -40% jw 65704/s 191% 44% 33% -- -9% -13% -20% -21% ted 72090/s 219% 58% 46% 10% -- -5% -12% -13% ike1b 75516/s 234% 65% 53% 15% 5% -- -8% -9% zaxo 82287/s 264% 80% 67% 25% 14% 9% -- -1% ike1 82719/s 266% 81% 68% 26% 15% 10% 1% --