55
66#include " BenchSink.hpp"
77
8+ #include < jalog/Instance.hpp>
89#include < jalog/Logger.hpp>
910#include < jalog/Scope.hpp>
1011#include < jalog/Log.hpp>
1112
1213#include < spdlog/spdlog.h>
1314#include < spdlog/logger.h>
15+ #include < spdlog/async_logger.h>
16+ #include < spdlog/async.h>
1417#include < spdlog/sinks/base_sink.h>
1518
1619#include < picobench/picobench.hpp>
1720
21+ #include < thread>
22+ #include < mutex>
23+
1824constexpr jalog::Level lcvt (spdlog::level::level_enum spdl) {
1925 using namespace spdlog ::level;
2026 using jalog::Level;
@@ -30,9 +36,10 @@ constexpr jalog::Level lcvt(spdlog::level::level_enum spdl) {
3036 }
3137}
3238
33- class SpdlogHashingSink : public spdlog ::sinks::base_sink<spdlog::details::null_mutex> {
39+ template <typename Mutex>
40+ class SpdlogHashingSink : public spdlog ::sinks::base_sink<Mutex> {
3441 size_t m_digest = 0 ;
35- public:
42+
3643 void sink_it_ (const spdlog::details::log_msg& msg) override {
3744 size_t d = 0 ;
3845 BenchSink::hashAppend (d,
@@ -45,7 +52,7 @@ class SpdlogHashingSink : public spdlog::sinks::base_sink<spdlog::details::null_
4552 m_digest ^= d;
4653 }
4754 void flush_ () override {}
48-
55+ public:
4956 size_t digest () const {
5057 return m_digest;
5158 }
@@ -54,7 +61,8 @@ class SpdlogHashingSink : public spdlog::sinks::base_sink<spdlog::details::null_
5461 }
5562};
5663
57- #include < jalog/LogPrintf.hpp>
64+ PICOBENCH_SUITE (" single thread" );
65+
5866void jalog_log (picobench::state& s) {
5967 jalog::Logger jl;
6068 auto sink = std::make_shared<BenchSink>();
@@ -69,7 +77,7 @@ void jalog_log(picobench::state& s) {
6977PICOBENCH (jalog_log);
7078
7179void spdlog_log (picobench::state& s) {
72- auto sink = std::make_shared<SpdlogHashingSink>();
80+ auto sink = std::make_shared<SpdlogHashingSink<spdlog::details::null_mutex> >();
7381 spdlog::logger spdl (" hi" , {sink});
7482
7583 for (auto i : s) {
@@ -78,3 +86,65 @@ void spdlog_log(picobench::state& s) {
7886 s.set_result (sink->digest ());
7987}
8088PICOBENCH (spdlog_log);
89+
90+ PICOBENCH_SUITE (" multi thread" );
91+
92+ constexpr size_t Num_Threads = 4 ;
93+
94+ void jalog_mt (picobench::state& s) {
95+ jalog::Logger jl;
96+ auto sink = std::make_shared<BenchSink>();
97+ jalog::Scope scope{jl, " mt" };
98+ jalog::Instance inst (jl);
99+ inst.setup ().async ().add (sink);
100+
101+ const int num_msg = s.iterations ();
102+
103+ std::vector<std::thread> threads;
104+ threads.reserve (Num_Threads);
105+
106+ {
107+ picobench::scope bench (s);
108+
109+ for (size_t i = 0 ; i < Num_Threads; ++i) {
110+ threads.emplace_back ([i, &scope, &num_msg]() {
111+ for (int imsg = 0 ; imsg < num_msg; ++imsg) {
112+ JALOG_SCOPE (scope, Info, " Thread " , i, " msg " , imsg);
113+ }
114+ });
115+ }
116+ for (auto & t : threads) t.join ();
117+ }
118+
119+ jl.flush ();
120+ s.set_result (sink->digest ());
121+ }
122+ PICOBENCH (jalog_mt);
123+
124+ void spdlog_mt (picobench::state& s) {
125+ auto sink = std::make_shared<SpdlogHashingSink<std::mutex>>();
126+ spdlog::init_thread_pool (s.iterations (), 1 );
127+ auto logger = std::make_shared<spdlog::async_logger>(" mt" , sink, spdlog::thread_pool ());
128+
129+ const int num_msg = s.iterations ();
130+
131+ std::vector<std::thread> threads;
132+ threads.reserve (Num_Threads);
133+
134+ {
135+ picobench::scope bench (s);
136+ for (size_t i = 0 ; i < Num_Threads; ++i) {
137+ threads.emplace_back ([i, &logger, &num_msg]() {
138+ for (int imsg = 0 ; imsg < num_msg; ++imsg) {
139+ logger->info (" Thread {} msg {}" , i, imsg);
140+ }
141+ });
142+ }
143+ for (auto & t : threads) t.join ();
144+ }
145+
146+ logger->flush ();
147+ spdlog::shutdown ();
148+ s.set_result (sink->digest ());
149+ }
150+ PICOBENCH (spdlog_mt);
0 commit comments