Bit-Set
view release on metacpan or search on metacpan
my $buffer_size = Bit_buffer_size(SIZE_OF_TEST_BIT);
my $scalar =
"\0" x $buffer_size;
my ( $buffer, $size ) =
scalar_to_buffer $scalar;
my $bytes =
Bit_extract( $bitset, $buffer );
my $first_byte = unpack( 'C', substr( $scalar, 0, 1 ) );
is( $first_byte, 0b00000101, 'Bit_extract produces correct buffer' );
Bit_free( \$bitset );
# test_bit_load
$scalar =
"\0" x $buffer_size;
( $buffer, $size ) =
scalar_to_buffer $scalar;
substr( $scalar, 0, 1 ) = pack( 'C', 0b00000101 );
$bitset = Bit_load( SIZE_OF_TEST_BIT, $buffer );
my $load_success =
( Bit_get( $bitset, 0 ) == 1 && Bit_get( $bitset, 2 ) == 1 );
ok( $load_success, 'Bit_load creates bitset from buffer correctly' );
Bit_free( \$bitset );
Example 6: Benchmarking of the Perl interface to the Bit library
This example re-implements part of the C benchmarking suite for the
Bit library (found in the source file "benchmark.c" in the github
repository for Bit <https://github.com/chrisarg/Bit>). The goal is to
compare the performance of various bitset operations in Perl with
their C counterparts, while showing a larger application that uses
the Perl interface to the Bit library. In this example we profile the
time it takes to execute the intersection and the count of the two
intersection of two bitsets with variable capacity, ranging from 128
to 1048576 bits. The intersection and the count of the intersection
is executed 1000 times and the time it takes to finish this benchmark
is used to infer the performance characteristics (nanoseconds per
iteration, iteration per second) of the Perl implementation compared
to the C implementation. There is negligible overhead introduced by
the Perl interface, making it a viable option for
performance-critical applications, without the "pain" of writing an
application in C. The github repo benchmarking-bits
<https://github.com/chrisarg/benchmarking-bits> contains an extensive
benchmarking suite that compares the performance of the FFI and XS
implementations of both the procedural and the OO interfaces of the
Bit::Set module against the C implementation of the Bit library.
use strict;
use warnings;
use Time::HiRes qw(gettimeofday tv_interval);
use Bit::Set qw(:all);
# Constants
use constant BPQW => 64; # bits per qword (8 bytes * 8 bits)
use constant BPB => 8; # bits per byte
# Test sizes and iterations
my @size_array = (
128, 256, 512, 1024, 2048, 4096, 8192, 16384,
32768, 65536, 131072, 262144, 524288, 1048576
);
my $iterations = 1000;
# Benchmark function registry
my %benchmark_funcs = (
'Count' => {
code => \&benchmark_bit_count,
descr => 'Count the number of bits set in the bitset'
},
'Inter Count' => {
code => \&benchmark_bit_inter_count,
descr => 'Count the number of bits set in an intersection'
},
);
print "Benchmarking the Perl Bit::Set library\n";
print "=" x 50, "\n";
for my $test ( sort keys %benchmark_funcs ) {
printf "%-15s => %s\n", $test, $benchmark_funcs{$test}{descr};
}
print "\n";
# Benchmark functions for each test type
sub benchmark_bit_count {
my ($size) = @_;
# Pre-create bitsets outside the benchmark
my $bit1 = Bit_new($size);
Bit_set( $bit1, int( $size / 2 ), $size - 1 );
Bit_bset( $bit1, 0 );
my $t0 = [gettimeofday];
my $result = Bit_count($bit1) for 1 .. $iterations;
my $t1 = [gettimeofday];
my $total_time = tv_interval $t0, $t1;
Bit_free( \$bit1 );
return $total_time;
}
sub benchmark_bit_inter_count {
my ($size) = @_;
# Pre-create bitsets outside the benchmark
my $bit1 = Bit_new($size);
my $bit2 = Bit_new($size);
Bit_set( $bit1, int( $size / 2 ), $size - 1 );
Bit_bset( $bit1, 0 );
my $t0 = [gettimeofday];
my $result = Bit_inter_count( $bit1, $bit2 ) for 1 .. $iterations;
my $t1 = [gettimeofday];
my $total_time = tv_interval $t0, $t1;
Bit_free( \$bit1 );
Bit_free( \$bit2 );
return $total_time;
}
sub run_benchmark {
my ( $test_name, $size, $benchmark_func ) = @_;
my $total_time = $benchmark_func->($size);
my $total_time_ns = $total_time * 1_000_000_000; # Convert to nanoseconds
# Calculate derived metrics
my $time_per_iteration = $total_time_ns / $iterations;
my $iterations_per_second = $iterations / $total_time;
# Format and print results
printf
"%-30s (size = %8d): %12.0f ns total\t%8.2f ns/iter\t%10.2e iter/s\n",
"Bit $test_name", $size, $total_time_ns, $time_per_iteration,
$iterations_per_second;
}
# Main benchmark execution
print "Running individual benchmarks...\n";
print "=" x 80, "\n";
for my $test_name ( sort keys %benchmark_funcs ) {
print "\nBenchmarking $test_name: $benchmark_funcs{$test_name}{descr}\n";
print "-" x 80, "\n";
for my $size (@size_array) {
run_benchmark( $test_name, $size, $benchmark_funcs{$test_name}{code} );
}
}
print "\n\nBenchmark completed!\n";
SEE ALSO
Alien::Bit <https://metacpan.org/pod/Alien::Bit>
This distribution provides the library Bit so that it can be used by
other Perl distributions that are on CPAN. It will download Bit from
Github and will build the (static and dynamic) versions of the
library for use by other Perl modules.
benchmarking-bits <https://github.com/chrisarg/benchmarking-bits>
A collection of benchmarking scripts for various bitset libraries in
C and Perl.
Bit <https://github.com/chrisarg/Bit>
Bit is a high-performance, uncompressed bitset implementation in C,
optimized for modern architectures. The library provides an efficient
way to create, manipulate, and query bitsets with a focus on
performance and memory alignment. The API and the interface is
largely based on David Hanson's Bit_T library discussed in Chapter 13
of "C Interfaces and Implementations", Addison-Wesley ISBN
0-201-49841-3 extended to incorporate additional operations (such as
counts on unions/differences/intersections of sets), fast population
counts using the libpocnt library and GPU operations for packed
containers of (collections) of Bit(sets).
Bit::Set::OO <https://metacpan.org/pod/Bit::Set::OO>
Object Oriented interface to the Bit::Set module.
Bit::Set::DB <https://metacpan.org/pod/Bit::Set::DB>
Procedural interface to the containerized operations of the Bit
library.
Bit::Set::DB::OO <https://metacpan.org/pod/Bit::Set::DB::OO>
Object Oriented interface to the Bit::Set::DB module.
Bit::Vector <https://metacpan.org/pod/Bit::Vector>
Efficient bit vector, set of integers and "big int" math library
( run in 0.531 second using v1.01-cache-2.11-cpan-71847e10f99 )