diff --git a/bench/meson.build b/bench/meson.build index 09004510..5ccbacb0 100644 --- a/bench/meson.build +++ b/bench/meson.build @@ -5,6 +5,7 @@ executable('bench-callback', sources: ['callback.cc'], dependencies: [fmt, tll]) executable('bench-callback-standalone', sources: ['callback-standalone.cc']) executable('bench-ring', sources: ['ring.cc', '../src/ring.c'], dependencies: [fmt], include_directories: include) executable('bench-refcount', sources: ['refcount.cc'], dependencies: [fmt, threads], include_directories: include) +executable('bench-stat', sources: ['stat.cc'], dependencies: [fmt, threads], include_directories: include) custom_target('tll-bench-channel.1' , output : 'tll-bench-channel.1' diff --git a/bench/stat.cc b/bench/stat.cc new file mode 100644 index 00000000..ff67e34b --- /dev/null +++ b/bench/stat.cc @@ -0,0 +1,80 @@ +#include +#include + +#include + +template +struct StatT +{ + tll::stat::FieldT f0; + tll::stat::FieldT f1; + tll::stat::FieldT f2; + tll::stat::GroupT grp; +}; + +using Stat = StatT; + +int acquire(tll::stat::Block * block, int value) +{ + if (auto p = block->acquire(); p) { + p->f0 = value; + block->release(p); + } + return value; +} + +int acquire_wait(tll::stat::Block * block, int value) +{ + if (auto p = block->acquire_wait(); p) { + p->f0 = 1; + block->release(p); + } + return value; +} + +template +inline int apply_func(tll::stat::Block * block, F func, Args... args) +{ + if (auto p = block->acquire(); p) { + func(p, std::forward(args)...); + block->release(p); + } + return 1; +} + +int apply(tll::stat::Block * block, int value) +{ + apply_func(block, [value](auto * p) { p->f0 = value; }); + return value; +} + +int main() +{ + using namespace std::chrono_literals; + constexpr unsigned count = 10000000; + tll::stat::Block block { "integer" }; + tll::bench::prewarm(100ms); + tll::bench::timeit(count, "acquire", acquire, &block, 1); + apply_func(&block, [](auto * p) { fmt::print("f0: {}\n", p->f0.value()); p->f0.reset(); }); + tll::bench::timeit(count, "acquire loop", acquire_wait, &block, 1); + apply_func(&block, [](auto * p) { fmt::print("f0: {}\n", p->f0.value()); p->f0.reset(); }); + tll::bench::timeit(count, "apply", apply, &block, 1); + apply_func(&block, [](auto * p) { fmt::print("f0: {}\n", p->f0.value()); p->f0.reset(); }); + bool stop = false; + auto thread = std::thread([](auto * stop, auto * block) { + while (!*stop) { + apply_func(block, [](auto p) { p->f1 = 1; }); + std::this_thread::yield(); + } + }, &stop, &block); + tll::bench::prewarm(1ms); + tll::bench::timeit(count, "thread + acquire", acquire, &block, 1); + apply_func(&block, [](auto * p) { fmt::print("f0: {}\n", p->f0.value()); p->f0.reset(); }); + tll::bench::timeit(count, "thread + acquire loop", acquire_wait, &block, 1); + apply_func(&block, [](auto * p) { fmt::print("f0: {}\n", p->f0.value()); p->f0.reset(); }); + tll::bench::timeit(count, "thread + apply", apply, &block, 1); + apply_func(&block, [](auto * p) { fmt::print("f0: {}\n", p->f0.value()); p->f0.reset(); }); + stop = true; + thread.join(); + return 0; +}