diff --git a/benchmark/Jamfile.v2 b/benchmark/Jamfile.v2 index ed42208..50307cb 100644 --- a/benchmark/Jamfile.v2 +++ b/benchmark/Jamfile.v2 @@ -14,5 +14,6 @@ project : requirements [ requires cxx14_generic_lambdas ] ; +exe bulk_comparison_table : bulk_comparison_table.cpp ; exe comparison_table : comparison_table.cpp ; exe fpr_c : fpr_c.cpp ; \ No newline at end of file diff --git a/benchmark/bulk_comparison_table.cpp b/benchmark/bulk_comparison_table.cpp new file mode 100644 index 0000000..9df29b7 --- /dev/null +++ b/benchmark/bulk_comparison_table.cpp @@ -0,0 +1,423 @@ +/* Comparison table of regular vs. bulk operations for several configurations + * of boost::bloom::filter. + * + * Copyright 2025 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See https://www.boost.org/libs/bloom for library home page. + */ + +#include +#include +#include +#include + +std::chrono::high_resolution_clock::time_point measure_start,measure_pause; + +template +double measure(F f) +{ + using namespace std::chrono; + + static const int num_trials=10; + static const milliseconds min_time_per_trial(10); + std::array trials; + + for(int i=0;i>(t2-measure_start).count()/runs; + } + + std::sort(trials.begin(),trials.end()); + return std::accumulate( + trials.begin()+2,trials.end()-2,0.0)/(trials.size()-4); +} + +void pause_timing() +{ + measure_pause=std::chrono::high_resolution_clock::now(); +} + +void resume_timing() +{ + measure_start+=std::chrono::high_resolution_clock::now()-measure_pause; +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static std::size_t num_elements; + +struct test_results +{ + double insertion_time; /* ns per element */ + double successful_lookup_time; /* ns per element */ + double unsuccessful_lookup_time; /* ns per element */ + double mixed_lookup_time; /* ns per element */ +}; + +template +test_results test(std::size_t c) +{ + using value_type=typename Filter::value_type; + + static constexpr double lookup_mix=0.1; /* successful pr. */ + static constexpr std::uint64_t mixed_lookup_cut= + (std::uint64_t)( + lookup_mix*(double)(std::numeric_limits::max)()); + + std::vector data_in,data_out,data_mixed; + { + boost::detail::splitmix64 rng; + boost::unordered_flat_set unique; + for(std::size_t i=0;i +bulk_test_results bulk_test(std::size_t c) +{ + using value_type=typename Filter::value_type; + + static constexpr double lookup_mix=0.5; + static constexpr std::uint64_t mixed_lookup_cut= + (std::uint64_t)( + lookup_mix*(double)(std::numeric_limits::max)()); + std::vector data_in,data_out,data_mixed; + { + boost::detail::splitmix64 rng; + boost::unordered_flat_set unique; + for(std::size_t i=0;i void row(std::size_t c) +{ + std::cout<< + " \n" + " "<\n"; + + boost::mp11::mp_for_each< + boost::mp11::mp_transform + >([&](auto i){ + using filter=typename decltype(i)::type; + auto res=test(c); + auto bulk_res=bulk_test(c); + std::cout<< + " "<\n" + " "<\n" + " "<\n" + " "<\n" + " "<\n"; + }); + + std::cout<< + " \n"; +} + +using namespace boost::bloom; + +template +using filters1=boost::mp11::mp_list< + filter, + filter>, + filter,1> +>; + +template +using filters2=boost::mp11::mp_list< + filter>, + filter,1>, + filter> +>; + +template +using filters3=boost::mp11::mp_list< + filter,1>, + filter>, + filter,1> +>; + +template +using filters4=boost::mp11::mp_list< + filter>, + filter,1>, + filter> +>; + +int main(int argc,char* argv[]) +{ + if(argc<2){ + std::cerr<<"provide the number of elements\n"; + return EXIT_FAILURE; + } + try{ + num_elements=std::stoul(argv[1]); + } + catch(...){ + std::cerr<<"wrong arg\n"; + return EXIT_FAILURE; + } + + /* table */ + + auto subheader= + " K\n" + " ins.\n" + " succ.
lkp.\n" + " uns.
lkp.\n" + " mixed
lkp.\n"; + + std::cout<< + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n"<< + subheader<< + subheader<< + subheader<< + " \n"; + + row>( 8); + row>(12); + row>(16); + row>(20); + + std::cout<< + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n"<< + subheader<< + subheader<< + subheader<< + " \n"; + + row>( 8); + row>(12); + row>(16); + row>(20); + + std::cout<< + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n"<< + subheader<< + subheader<< + subheader<< + " \n"; + + row>( 8); + row>(12); + row>(16); + row>(20); + + std::cout<< + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n"<< + subheader<< + subheader<< + subheader<< + " \n"; + + row>( 8); + row>(12); + row>(16); + row>(20); + + std::cout<<"
filter<int,K>filter<int,1,block<uint64_t,K>>filter<int,1,block<uint64_t,K>,1>
c
filter<int,1,multiblock<uint64_t,K>>filter<int,1,multiblock<uint64_t,K>,1>filter<int,1,fast_multiblock32<K>>
c
filter<int,1,fast_multiblock32<K>,1>filter<int,1,fast_multiblock64<K>>filter<int,1,fast_multiblock64<K>,1>
c
filter<int,1,block<uint64_t[8],K>>filter<int,1,block<uint64_t[8],K>,1>filter<int,1,multiblock<uint64_t[8],K>>
c
\n"; +} diff --git a/doc/bloom.adoc b/doc/bloom.adoc index f6797e4..7c8645a 100644 --- a/doc/bloom.adoc +++ b/doc/bloom.adoc @@ -12,6 +12,7 @@ :stem: latexmath :small: pass:[] :small-end: pass:[] +:cpp: C++ ++++