Looks like the double negative way is the fastest except for the empty set. In all other cases the ones comparing the array to the grep'd version may have a lot of comparisons to do before they discover inequality.
#!/usr/bin/perl -l
use strict;
use warnings;
use Benchmark;
my (@a, @b, @c, @d, @e);
@a=({}, {}, {}, {}, {}, {}, {}, {}, {}, {});
push @b, @a for (1..10000);
push @c, @b, "a";
push @d, "a", @b;
@e=();
sub trinary {
my $a=shift;
print ((@$a == grep {ref $_ eq "HASH"} @$a) ? @$a ? 1 : 0 : 0)
}
sub double_neg {
my $a=shift;
print @$a && !grep({ref($_) ne 'HASH'} @$a);
}
sub equality {
my $a=shift;
print @$a && @$a == grep({ref($_) eq 'HASH'} @$a);
}
timethese(9000000, {
'a trinary' => trinary(\@a),
'a double_neg' => double_neg(\@a),
'a equality' => equality(\@a),
'b trinary' => trinary(\@b),
'b double_neg' => double_neg(\@b),
'b equality' => equality(\@b),
'c trinary' => trinary(\@c),
'c double_neg' => double_neg(\@c),
'c equality' => equality(\@c),
'd trinary' => trinary(\@d),
'd double_neg' => double_neg(\@d),
'd equality' => equality(\@d),
'e trinary' => trinary(\@e),
'e double_neg' => double_neg(\@e),
'e equality' => equality(\@e),
});
__DATA__
a double_neg: -1 wallclock secs ( 0.47 usr + 0.09 sys = 0.56 CPU) @
+16071428.57/s (n=9000000)
a equality: -1 wallclock secs ( 0.62 usr + -0.01 sys = 0.61 CPU) @
+14754098.36/s (n=9000000)
a trinary: 4 wallclock secs ( 0.81 usr + 0.05 sys = 0.86 CPU) @
+10465116.28/s (n=9000000)
b double_neg: 3 wallclock secs ( 0.72 usr + 0.00 sys = 0.72 CPU) @
+12500000.00/s (n=9000000)
b equality: 0 wallclock secs ( 0.75 usr + -0.07 sys = 0.68 CPU) @
+13235294.12/s (n=9000000)
b trinary: 6 wallclock secs ( 0.77 usr + 0.00 sys = 0.77 CPU) @
+11688311.69/s (n=9000000)
c double_neg: -2 wallclock secs ( 0.52 usr + -0.02 sys = 0.50 CPU) @
+18000000.00/s (n=9000000)
c equality: 3 wallclock secs ( 0.61 usr + 0.07 sys = 0.68 CPU) @
+13235294.12/s (n=9000000)
c trinary: 0 wallclock secs ( 0.54 usr + 0.00 sys = 0.54 CPU) @
+16666666.67/s (n=9000000)
d double_neg: -4 wallclock secs ( 0.29 usr + 0.00 sys = 0.29 CPU) @
+31034482.76/s (n=9000000)
(warning: too few iterations for a reliable count)
d equality: 0 wallclock secs ( 0.69 usr + 0.00 sys = 0.69 CPU) @
+13043478.26/s (n=9000000)
d trinary: 2 wallclock secs ( 0.56 usr + -0.05 sys = 0.51 CPU) @
+17647058.82/s (n=9000000)
e double_neg: 7 wallclock secs ( 0.77 usr + 0.06 sys = 0.83 CPU) @
+10843373.49/s (n=9000000)
e equality: 1 wallclock secs ( 0.62 usr + 0.00 sys = 0.62 CPU) @
+14516129.03/s (n=9000000)
e trinary: 1 wallclock secs ( 0.53 usr + 0.06 sys = 0.59 CPU) @
+15254237.29/s (n=9000000)
Cheers, R.
Pereant, qui ante nos nostra dixerunt!
|