! /usr/bin/perl -w
use strict;
my %h = (
a => 1,
b => undef,
c => 1,
d => 1,
e => undef,
);
my @def;
$def[ defined $_ ? 1 : 0]++ for values %h;
print "undefined=$def[0], defined=$def[1]\n";
__END__
produces:
undefined=2, defined=3
####
#! /usr/bin/perl -w
use strict;
use Benchmark qw/cmpthese/;
my %h;
my $nr = shift || 10000000;
$h{$nr} = ((rand() > 0.2) ? 1 : undef) while $nr--;
sub by_for {
my $h = shift;
my @def;
$def[ defined $_ ? 1 : 0]++ for values %$h;
@def;
}
sub by_grep {
my $h = shift;
(
scalar (grep !defined, values %$h),
scalar (grep defined, values %$h),
);
}
printf "by_for: undefined=%d, defined=%d\n", by_for( \%h );
printf "by_grep: undefined=%d, defined=%d\n", by_grep( \%h );
cmpthese( -5, {
for => ' by_for( \%h ) ',
grep => ' by_grep( \%h ) ',
}
);
####
by_for: undefined=2000300, defined=7999700
by_grep: undefined=2000300, defined=7999700
Benchmark: running for, grep for at least 5 CPU seconds...
for: 5 wallclock secs ( 5.27 usr + 0.00 sys = 5.27 CPU) @ 163521.04/s (n=862318)
grep: 6 wallclock secs ( 5.05 usr + 0.00 sys = 5.05 CPU) @ 224222.12/s (n=1131621)
Rate for grep
for 163521/s -- -27%
grep 224222/s 37% --
####
cmpthese( -300, {
byfor => sub { by_for( \%h ) },
bygrep => sub { by_grep( \%h ) },
}
);
####
by_for: undefined=2398233, defined=9601767
by_grep: undefined=2398233, defined=9601767
Benchmark: running byfor, bygrep for at least 300 CPU seconds...
byfor: 311 wallclock secs (311.09 usr + 0.03 sys = 311.12 CPU) @ 0.06/s (n=20)
bygrep: 313 wallclock secs (312.95 usr + 0.04 sys = 312.99 CPU) @ 0.04/s (n=13)
s/iter bygrep byfor
bygrep 24.1 -- -35%
byfor 15.6 55% --
####
sub by_diff {
my $h = shift;
my $defined = grep defined, values %$h;
(
scalar keys(%$h) - $defined,
$defined,
);
}
printf "by_for: undefined=%d, defined=%d\n", by_for( \%h );
printf "by_grep: undefined=%d, defined=%d\n", by_grep( \%h );
printf "by_diff: undefined=%d, defined=%d\n", by_diff( \%h );
cmpthese( -600, {
byfor => sub { by_for( \%h ) },
bygrep => sub { by_grep( \%h ) },
bydiff => sub { by_diff( \%h ) },
}
);
####
by_for: undefined=2398740, defined=9601260
by_grep: undefined=2398740, defined=9601260
by_diff: undefined=2398740, defined=9601260
Benchmark: running bydiff, byfor, bygrep for at least 600 CPU seconds...
bydiff: 606 wallclock secs (604.93 usr + 0.11 sys = 605.04 CPU) @ 0.08/s (n=51)
byfor: 625 wallclock secs (623.32 usr + 0.09 sys = 623.41 CPU) @ 0.06/s (n=40)
bygrep: 604 wallclock secs (602.22 usr + 0.07 sys = 602.29 CPU) @ 0.04/s (n=25)
s/iter bygrep byfor bydiff
bygrep 24.1 -- -35% -51%
byfor 15.6 55% -- -24%
bydiff 11.9 103% 31% --