%---------------------------------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %---------------------------------------------------------------------------% :- module speedtest_bitset. :- interface. :- import_module io. :- pred main(io::di, io::uo) is cc_multi. %---------------------------------------------------------------------------% %---------------------------------------------------------------------------% :- implementation. :- import_module benchmarking. :- import_module fat_sparse_bitset. :- import_module fatter_sparse_bitset. :- import_module float. :- import_module int. :- import_module list. :- import_module maybe. :- import_module pair. :- import_module random. :- import_module random.sfc64. :- import_module random.system_rng. :- import_module sparse_bitset. :- import_module string. :- import_module uint. %---------------------------------------------------------------------------% main(!IO) :- io.command_line_arguments(Args, !IO), ( if ( Args = [], Size = 80000u, Repeat = 4000 ; Args = [SizeStr], string.to_uint(SizeStr, Size), Repeat = 1000 ; Args = [SizeStr, RepeatStr], string.to_uint(SizeStr, Size), string.to_int(RepeatStr, Repeat) ) then init_random(MaybeRNG, !IO), ( MaybeRNG = ok(R0), build_random_list(Size, 2u, [], BenchList, R0, _R), run_benchmarks(Repeat, BenchList, !IO) ; MaybeRNG = error(_), io.write_string("init_random failed\n", !IO) ) else io.write_string("usage: speedtest_bitset [Size [Repeat]]\n", !IO) ). %---------------------------------------------------------------------------% :- type bench ---> bench(uint, uint, list(uint)). % stride, #elems, random list with that stride and #elems :- pred build_random_list(uint::in, uint::in, list(bench)::in, list(bench)::out, R::in, R::out) is det <= random(R). build_random_list(Size, Stride, !BenchList, !R) :- NumElems = Size / Stride, ( if NumElems =< 64u then true else build_random_list_acc(Size, NumElems, [], RandomList, !R), Bench = bench(Stride, NumElems, RandomList), !:BenchList = [Bench | !.BenchList], build_random_list(Size, Stride * 2u, !BenchList, !R) ). :- pred build_random_list_acc(uint::in, uint::in, list(uint)::in, list(uint)::out, R::in, R::out) is det <= random(R). build_random_list_acc(Size, NumElemsLeft, !RandomList, !R) :- ( if NumElemsLeft = 0u then true else random.uniform_uint_in_range(0u, Size, Random, !R), !:RandomList = [Random | !.RandomList], build_random_list_acc(Size, NumElemsLeft - 1u, !RandomList, !R) ). %---------------------------------------------------------------------------% :- pred run_benchmarks(int::in, list(bench)::in, io::di, io::uo) is cc_multi. run_benchmarks(_Repeat, [], !IO). run_benchmarks(Repeat, [Bench | Benches], !IO) :- Bench = bench(Stride, NumElems, RandomList), io.write_string("--------------------\n\n", !IO), io.format("stride: %u\n", [u(Stride)], !IO), io.format("#elems: %u\n", [u(NumElems)], !IO), io.format("#repeat: %d\n", [i(Repeat)], !IO), benchmark_det(bench_sparse, RandomList, SparseSet, Repeat, TimeSparse), benchmark_det(bench_fat_sparse, RandomList, FatSparseSet, Repeat, TimeFatSparse), benchmark_det(bench_fatter_sparse, RandomList, FatterSparseSet, Repeat, TimeFatterSparse), sparse_bitset.to_sorted_list(SparseSet, SparseSortedList), fat_sparse_bitset.to_sorted_list(FatSparseSet, FatSparseSortedList), fatter_sparse_bitset.to_sorted_list(FatterSparseSet, FatterSparseSortedList), list.sort_and_remove_dups(RandomList, SortedList), ( if SparseSortedList = SortedList, FatSparseSortedList = SortedList, FatterSparseSortedList = SortedList then AvgSparse = float(TimeSparse) / float(Repeat), AvgFatSparse = float(TimeFatSparse) / float(Repeat), AvgFatterSparse = float(TimeFatterSparse) / float(Repeat), io.format("sparse: %12.5f ms\n", [f(AvgSparse)], !IO), io.format("fat sparse: %12.5f ms\n", [f(AvgFatSparse)], !IO), io.format("fatter sparse: %12.5f ms\n", [f(AvgFatterSparse)], !IO) else io.write_string("SORTED LIST MISMATCH\n", !IO) ), io.nl(!IO), io.flush_output(!IO), run_benchmarks(Repeat, Benches, !IO). :- pred bench_sparse(list(uint)::in, sparse_bitset(uint)::out) is det. bench_sparse(RandomList, Set) :- sparse_bitset.list_to_set(RandomList, Set). :- pred bench_fat_sparse(list(uint)::in, fat_sparse_bitset(uint)::out) is det. bench_fat_sparse(RandomList, Set) :- fat_sparse_bitset.list_to_set(RandomList, Set). :- pred bench_fatter_sparse(list(uint)::in, fatter_sparse_bitset(uint)::out) is det. bench_fatter_sparse(RandomList, Set) :- fatter_sparse_bitset.list_to_set(RandomList, Set). %---------------------------------------------------------------------------% :- some [R] pred init_random(maybe_error(R)::out, io::di, io::uo) is det => random(R). init_random(Res, !IO) :- open_system_rng(MaybeRNG, !IO), ( MaybeRNG = ok(SystemRNG), system_rng.generate_uint64(SystemRNG, A, !IO), system_rng.generate_uint64(SystemRNG, B, !IO), system_rng.generate_uint64(SystemRNG, C, !IO), close_system_rng(SystemRNG, !IO), sfc64.seed(A, B, C, Params, UState), R = make_shared_random(Params, UState), Res = ok(R) ; MaybeRNG = error(Error), Res = error(Error) ). %---------------------------------------------------------------------------%