This benchmark seems reasonable. I made a couple small changes: set the count to a negative interval, which makes it run each for "n" seconds, and increased the array size.
I do have List::MoreUtils, so I added mine to the benchmark test. My solution fell square in the middle of the pack. Here are the results I get:
Rate kennethk_1 kennethk_2 kennethk_3 Cristoforo anilm
+wr kcott davido Anonymous_Monk roboticus_2 dbuckhal GrandFather robot
+icus_1 SuicideJunkie
kennethk_1 260/s -- -3% -7% -46% -5
+2% -55% -56% -57% -68% -68% -69%
+ -69% -71%
kennethk_2 267/s 3% -- -4% -45% -5
+1% -53% -55% -55% -67% -68% -68%
+ -68% -70%
kennethk_3 278/s 7% 4% -- -42% -4
+9% -51% -53% -54% -66% -66% -66%
+ -66% -68%
Cristoforo 482/s 86% 81% 73% -- -1
+1% -16% -19% -20% -41% -41% -42%
+ -42% -45%
anilmwr 544/s 110% 104% 96% 13%
+-- -5% -9% -9% -33% -34% -34%
+ -34% -38%
kcott 573/s 121% 115% 106% 19%
+5% -- -4% -4% -30% -30% -31%
+ -31% -35%
davido 595/s 129% 123% 114% 23%
+9% 4% -- -1% -27% -28% -28%
+ -28% -33%
Anonymous_Monk 600/s 131% 125% 115% 24% 1
+0% 5% 1% -- -27% -27% -27%
+ -28% -32%
roboticus_2 817/s 215% 206% 194% 69% 5
+0% 43% 37% 36% -- -1% -1%
+ -1% -7%
dbuckhal 823/s 217% 208% 196% 71% 5
+1% 44% 38% 37% 1% -- -0%
+ -1% -7%
GrandFather 826/s 218% 209% 197% 71% 5
+2% 44% 39% 38% 1% 0% --
+ -0% -6%
roboticus_1 830/s 220% 211% 198% 72% 5
+2% 45% 39% 38% 2% 1% 0%
+ -- -6%
SuicideJunkie 882/s 240% 230% 217% 83% 6
+2% 54% 48% 47% 8% 7% 7%
+ 6% --
...and the code...
use strict;
use warnings;
use 5.010;
use Benchmark 'cmpthese';
use List::MoreUtils 'part';
our @orig_array = map { int rand 4 } 1 .. 5000;
my $count = -5;
cmpthese($count, {
anilmwr => \&anilmwr,
roboticus_1 => \&roboticus_1,
roboticus_2 => \&roboticus_2,
kennethk_1 => \&kennethk_1,
kennethk_2 => \&kennethk_2,
kennethk_3 => \&kennethk_3,
Anonymous_Monk => \&Anonymous_Monk,
SuicideJunkie => \&SuicideJunkie,
kcott => \&kcott,
GrandFather => \&GrandFather,
Cristoforo => \&Cristoforo,
dbuckhal => \&dbuckhal,
davido => \&davido,
});
sub anilmwr { # Fixed but keeping the concept of the original
my @array = @main::orig_array;
my @array1 = ();
my @array2 = ();
foreach my $i (@array) {
push @array1, $i if $i == 0;
push @array2, $i if $i != 0;
}
my @new_array = (@array1, @array2);
}
sub roboticus_1 {
my @array = @main::orig_array;
my @new_array=();
for my $i (@array) {
if ($i) {
push @new_array, $i;
}
else {
unshift @new_array, $i;
}
}
}
sub roboticus_2 {
my @array = @main::orig_array;
my @new_array = (
grep( { ! $_ } @array),
grep( { $_ } @array)
);
}
sub kennethk_1 {
my @array = @main::orig_array;
@array = sort {-($a == 0) || $b == 0} @array;
}
sub kennethk_2 {
my @array = @main::orig_array;
@array = sort {($b == 0)-($a == 0)} @array;
}
sub kennethk_3 {
my @array = @main::orig_array;
@array = sort {!$b - !$a} @array;
}
sub davido {
my @array = @main::orig_array;
@array = map { @$_ } part { !!$_ } @array;
}
sub Anonymous_Monk {
my @array = @main::orig_array;
@array = do { my @tmp = grep $_, @array; ((0)x(@array-@tmp),@tmp)
+};
}
sub SuicideJunkie {
my @array = @main::orig_array;
my $size = @array;
@array = grep {$_} @array;
unshift @array, (0) x ($size - @array);
}
sub kcott {
my @array = @main::orig_array;
my $zeros = 0;
@array = map { $_ == 0 ? ++$zeros && () : $_ } @array;
unshift @array, (0) x $zeros;
}
sub GrandFather {
my @array = @main::orig_array;
my @newArray = grep{!$_} @array;
push @newArray, grep {$_} @array;
}
sub Cristoforo {
my @array = @main::orig_array;
for my $i (0 .. $#array) {
unshift @array, splice @array, $i, 1 if $array[$i] == 0;
}
}
sub dbuckhal {
my @array = @main::orig_array;
my @y;
for ( @array ) {
( $_ ) ? push @y, $_ : unshift @y, $_;
}
}
I still like the semantic purity of the List::MoreUtils 'part'; solution, but beauty is probably in the eye of the beholder. ;)