Use google benchmark to test latency
This commit is contained in:
		
							parent
							
								
									240a58fd6e
								
							
						
					
					
						commit
						121a7dcedf
					
				| @ -16,7 +16,7 @@ async_bench: async_bench.cpp | |||||||
| 	 | 	 | ||||||
| 	 | 	 | ||||||
| latency: latency.cpp | latency: latency.cpp | ||||||
| 	$(CXX) latency.cpp -o latency $(CXXFLAGS) $(CXX_RELEASE_FLAGS) | 	$(CXX) latency.cpp -o latency $(CXXFLAGS) $(CXX_RELEASE_FLAGS) -lbenchmark | ||||||
| 				 | 				 | ||||||
| 
 | 
 | ||||||
| .PHONY: clean | .PHONY: clean | ||||||
|  | |||||||
| @ -7,6 +7,8 @@ | |||||||
| // latency.cpp : spdlog latency benchmarks
 | // latency.cpp : spdlog latency benchmarks
 | ||||||
| //
 | //
 | ||||||
| 
 | 
 | ||||||
|  | #include "benchmark/benchmark.h" | ||||||
|  | 
 | ||||||
| #include "spdlog/spdlog.h" | #include "spdlog/spdlog.h" | ||||||
| #include "spdlog/async.h" | #include "spdlog/async.h" | ||||||
| #include "spdlog/sinks/basic_file_sink.h" | #include "spdlog/sinks/basic_file_sink.h" | ||||||
| @ -14,6 +16,7 @@ | |||||||
| #include "spdlog/sinks/null_sink.h" | #include "spdlog/sinks/null_sink.h" | ||||||
| #include "spdlog/sinks/rotating_file_sink.h" | #include "spdlog/sinks/rotating_file_sink.h" | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #include "utils.h" | #include "utils.h" | ||||||
| #include <atomic> | #include <atomic> | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| @ -31,123 +34,51 @@ using namespace utils; | |||||||
| void bench(int howmany, std::shared_ptr<spdlog::logger> log); | void bench(int howmany, std::shared_ptr<spdlog::logger> log); | ||||||
| void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count); | void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count); | ||||||
| 
 | 
 | ||||||
| int main(int, char *[]) | void bench_c_string(benchmark::State& state, std::shared_ptr<spdlog::logger> logger) | ||||||
| { | { | ||||||
|     std::srand(static_cast<unsigned>(std::time(nullptr))); // use current time as seed for random generator
 |     const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus " | ||||||
|     int howmany = 1000000; |                       "lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, eu consequat sem " | ||||||
|     int queue_size = howmany + 2; |                       "libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec fringilla dui sed " | ||||||
|     int threads = 10; |                       "augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, nisi turpis ornare " | ||||||
|     size_t file_size = 30 * 1024 * 1024; |                       "nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis."; | ||||||
|     size_t rotating_files = 5; |  | ||||||
| 
 | 
 | ||||||
|     try | 
 | ||||||
|  |     for (auto _ : state) | ||||||
|     { |     { | ||||||
| 
 |         logger->info(msg); | ||||||
|         cout << "******************************************************************" |  | ||||||
|                 "*************\n"; |  | ||||||
|         cout << "Single thread\n"; |  | ||||||
|         cout << "******************************************************************" |  | ||||||
|                 "*************\n"; |  | ||||||
| 
 |  | ||||||
|         auto basic_st = spdlog::basic_logger_mt("basic_st", "logs/basic_st.log", true); |  | ||||||
|         bench(howmany, basic_st); |  | ||||||
| 
 |  | ||||||
|         auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files); |  | ||||||
|         bench(howmany, rotating_st); |  | ||||||
| 
 |  | ||||||
|         auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log"); |  | ||||||
|         bench(howmany, daily_st); |  | ||||||
| 
 |  | ||||||
|         bench(howmany, spdlog::create<null_sink_st>("null_st")); |  | ||||||
| 
 |  | ||||||
|         cout << "\n****************************************************************" |  | ||||||
|                 "***************\n"; |  | ||||||
|         cout << threads << " threads sharing same logger\n"; |  | ||||||
|         cout << "******************************************************************" |  | ||||||
|                 "*************\n"; |  | ||||||
| 
 |  | ||||||
|         auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true); |  | ||||||
|         bench_mt(howmany, basic_mt, threads); |  | ||||||
| 
 |  | ||||||
|         auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files); |  | ||||||
|         bench_mt(howmany, rotating_mt, threads); |  | ||||||
| 
 |  | ||||||
|         auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log"); |  | ||||||
|         bench_mt(howmany, daily_mt, threads); |  | ||||||
|         bench(howmany, spdlog::create<null_sink_st>("null_mt")); |  | ||||||
| 
 |  | ||||||
|         cout << "\n****************************************************************" |  | ||||||
|                 "***************\n"; |  | ||||||
|         cout << "async logging.. " << threads << " threads sharing same logger\n"; |  | ||||||
|         cout << "******************************************************************" |  | ||||||
|                 "*************\n"; |  | ||||||
| 
 |  | ||||||
|         for (int i = 0; i < 3; ++i) |  | ||||||
|         { |  | ||||||
|             spdlog::init_thread_pool(static_cast<size_t>(queue_size), 1); |  | ||||||
|             auto as = spdlog::basic_logger_mt<spdlog::async_factory>("async", "logs/basic_async.log", true); |  | ||||||
|             bench_mt(howmany, as, threads); |  | ||||||
|             spdlog::drop("async"); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|     catch (std::exception &ex) | 
 | ||||||
|  | void bench_formatted_int(benchmark::State& state, std::shared_ptr<spdlog::logger> logger) | ||||||
| { | { | ||||||
|         std::cerr << "Error: " << ex.what() << std::endl; | 
 | ||||||
|         perror("Last error"); |     int i = 0; | ||||||
|         return EXIT_FAILURE; |     for (auto _ : state) | ||||||
|  |     { | ||||||
|  |         logger->info("Hello message {} {} {}", ++i, i , i); | ||||||
|     } |     } | ||||||
|     return EXIT_SUCCESS; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bench(int howmany, std::shared_ptr<spdlog::logger> log) |  | ||||||
| { |  | ||||||
|     using namespace std::chrono; |  | ||||||
|     using chrono::high_resolution_clock; |  | ||||||
|     using chrono::milliseconds; |  | ||||||
|     using chrono::nanoseconds; |  | ||||||
| 
 | 
 | ||||||
|     cout << log->name() << "...\t\t" << flush; | 
 | ||||||
|     nanoseconds total_nanos = nanoseconds::zero(); | 
 | ||||||
|     for (auto i = 0; i < howmany; ++i) | int main(int argc, char *argv[]) | ||||||
| { | { | ||||||
|         auto start = high_resolution_clock::now(); | 
 | ||||||
|         log->info("Hello logger: msg number {}", i); |     using spdlog::sinks::null_sink_st ; | ||||||
|         auto delta_nanos = chrono::duration_cast<nanoseconds>(high_resolution_clock::now() - start); |     using spdlog::sinks::null_sink_mt ; | ||||||
|         total_nanos += delta_nanos; | 
 | ||||||
|     } |     auto null_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_st>()); | ||||||
| 
 |     benchmark::RegisterBenchmark("null_sink_st-500_bytes_cstr", bench_c_string, null_logger); | ||||||
|     auto avg = total_nanos.count() / howmany; |     benchmark::RegisterBenchmark("null_sink_st-formatted_int", bench_formatted_int, null_logger); | ||||||
|     cout << format(avg) << " ns/call" << endl; | 
 | ||||||
| } |     // 10 threads
 | ||||||
| 
 |     int n_threads = 10; | ||||||
| void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count) |     null_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_st>()); | ||||||
| { |     benchmark::RegisterBenchmark("null_sink_mt-500_bytes_cstr", bench_c_string, null_logger) -> Threads(n_threads); | ||||||
|     using namespace std::chrono; |     benchmark::RegisterBenchmark("null_sink_mt-formatted_int", bench_formatted_int, null_logger) ->Threads(n_threads); | ||||||
|     using chrono::high_resolution_clock; |      | ||||||
|     using chrono::milliseconds; |     benchmark::Initialize(&argc, argv); | ||||||
|     using chrono::nanoseconds; |     benchmark::RunSpecifiedBenchmarks(); | ||||||
| 
 | 
 | ||||||
|     cout << log->name() << "...\t\t" << flush; |  | ||||||
|     vector<thread> threads; |  | ||||||
|     std::atomic<nanoseconds::rep> total_nanos{0}; |  | ||||||
|     for (int t = 0; t < thread_count; ++t) |  | ||||||
|     { |  | ||||||
|         threads.push_back(std::thread([&]() { |  | ||||||
|             for (int j = 0; j < howmany / thread_count; j++) |  | ||||||
|             { |  | ||||||
|                 auto start = high_resolution_clock::now(); |  | ||||||
|                 log->info("Hello logger: msg number {}", j); |  | ||||||
|                 auto delta_nanos = chrono::duration_cast<nanoseconds>(high_resolution_clock::now() - start); |  | ||||||
|                 total_nanos += delta_nanos.count(); |  | ||||||
|             } |  | ||||||
|         })); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     for (auto &t : threads) |  | ||||||
|     { |  | ||||||
|         t.join(); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     auto avg = total_nanos / howmany; |  | ||||||
|     cout << format(avg) << " ns/call" << endl; |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user