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; }