my @bools;
$bools[0] = 1; # element 0 is true
$bools[1] = ''; # element 1 is false
####
my @trues = grep $bools[$_], 0 .. $#bools;
####
my $bools;
vec( $bools, 0, 1 ) = 1; # element 0 is true
vec( $bools, 1, 1 ) = 0; # element 1 is false
####
my @trues = grep vec( $bools, $_, 1 ), 0 .. 8 * length $bools;
####
foreach my $i ( 0 .. 8 * length $bools ) {
push @trues, $i if vec( $bools, $i, 1 );
}
####
# for each character, count the on bits in that character
my %bits_in;
foreach my $char ( map { chr } 0 .. 255 ) {
foreach my $bit ( 0 .. 7 ) {
$bits_in{ $char } += vec( $char, $bit, 1 );
}
}
my $count;
$count += $bits_in{ $1 } while ( $bools =~ m{([^\000])}g );
####
my $count;
$count += $bits_in{ chop $bits } while $bits;
####
my $count;
$count += $bits_in{ substr $bits, $_, 1 } for 0 .. length( $bits ) - 1;
####
use Benchmark qw( cmpthese );
my %bits_in;
foreach my $char ( map { chr } 0 .. 255 ) {
foreach my $bit ( 0 .. 7 ) {
$bits_in{ $char } += vec( $char, $bit, 1 );
}
}
my @tests = (
[ 8, 1 ],
[ 8, 8 ],
[ 1_000, 1 ],
[ 1_000, 10 ],
[ 1_000, 100 ],
[ 1_000, 500 ],
[ 1_000, 900 ],
[ 1_000_000, 1 ],
[ 1_000_000, 100 ],
[ 1_000_000, 100_000 ],
[ 1_000_000, 500_000 ],
[ 1_000_000, 900_000 ],
);
#use Test::More;
#plan 'tests' => 3 * scalar @tests;
foreach my $t ( @tests ) {
my $bits = mkbits( @{ $t } );
printf "%d, %d\n", @{ $t };
# my $v = vec_count( $bits );
# is( $v, re_count( $bits ), "re counted $v" );
# is( $v, chop_count( $bits ), "chop counted $v" );
# is( $v, loop_count( $bits ), "loop counted $v" );
cmpthese( -1, {
'vec' => sub { vec_count( $bits ) },
're' => sub { re_count( $bits ) },
'chop' => sub { chop_count( $bits ) },
'loop' => sub { loop_count( $bits ) },
}
);
}
sub chop_count {
my ( $bits ) = @_;
my $count;
$count += $bits_in{ chop $bits } while $bits;
return $count;
}
sub vec_count {
my ( $bits ) = @_;
my $bit_count = length( $bits ) * 8;
my $count;
$count += vec( $bits, $_, 1 ) for 0 .. $bit_count;
return $count;
}
sub re_count {
my ( $bits ) = @_;
my $count;
$count += $bits_in{ $1 } while ( $bits =~ m{([^\000])}g );
return $count;
}
sub loop_count {
my ( $bits ) = @_;
my $count;
$count += $bits_in{ substr $bits, $_, 1 } for 0 .. length( $bits ) - 1;
return $count;
}
sub mkbits {
my ( $bitcount, $ones ) = @_;
my $bits = "\000" x int( $bitcount / 8 );
while ( $ones-- ) {
vec( $bits, rand $bitcount, 1 ) = 1;
}
return $bits;
}