1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2/* 3 * Copyright 2018 Couchbase, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18#include <benchmark/benchmark.h> 19 20#include <boost/optional/optional.hpp> 21#include <logger/logger.h> 22#include <logger/logger_config.h> 23#include <iostream> 24 25/** 26 * A fixture for benchmarking the logger. 27 */ 28class LoggerBench : public benchmark::Fixture { 29protected: 30 void SetUp(const benchmark::State& state) override; 31 32 void TearDown(const benchmark::State& state) override { 33 if (state.thread_index == 0) { 34 if (cb::logger::isInitialized()) { 35 cb::logger::shutdown(); 36 } else { 37 std::cerr << "Failed to shutdown logger as it was never " 38 "initialized in the first place"; 39 return; 40 } 41 } 42 } 43}; 44 45void LoggerBench::SetUp(const benchmark::State& state) { 46 if (state.thread_index == 0) { 47 cb::logger::Config config{}; 48 config.cyclesize = 2048; 49 config.buffersize = 8192; 50 config.unit_test = true; 51 config.console = false; 52 53 auto init = cb::logger::initialize(config); 54 if (init) { 55 std::cerr << "Failed to initialize logger: " << *init; 56 return; 57 } 58 59 cb::logger::get()->set_level(spdlog::level::level_enum::warn); 60 } 61} 62 63class LoggerBench_Blackhole : public LoggerBench { 64protected: 65 void SetUp(const benchmark::State& state) override { 66 if (state.thread_index == 0) { 67 cb::logger::createBlackholeLogger(); 68 } 69 } 70}; 71 72/** 73 * Benchmark the cost of logging to a level which is dropped. 74 * We're currently using the async logging (which is the one 75 * we'll be using "in production".. except that we don't have 76 * the file-backend writing to the disk 77 */ 78BENCHMARK_DEFINE_F(LoggerBench, LogToLoggerWithDisabledLogLevel) 79(benchmark::State& state) { 80 while (state.KeepRunning()) { 81 LOG_TRACE("Foo"); 82 } 83} 84 85/** 86 * Benchmark the cost of logging to a level which is enabled (moved 87 * to the sink). 88 * We're currently using the async logging (which is the one 89 * we'll be using "in production".. except that we don't have 90 * the file-backend writing to the disk 91 */ 92BENCHMARK_DEFINE_F(LoggerBench, LogToLoggerWithEnabledLogLevel) 93(benchmark::State& state) { 94 if (state.thread_index == 0) { 95 cb::logger::get()->set_level(spdlog::level::level_enum::trace); 96 } 97 while (state.KeepRunning()) { 98 LOG_TRACE("Foo"); 99 } 100} 101 102/** 103 * Benchmark the cost of grabbing the logger (which means checking 104 * for it's existence and copy a shared pointer). 105 */ 106BENCHMARK_DEFINE_F(LoggerBench_Blackhole, GetLogger)(benchmark::State& state) { 107 while (state.KeepRunning()) { 108 auto logger = cb::logger::get(); 109 benchmark::DoNotOptimize(logger); 110 } 111} 112 113BENCHMARK_REGISTER_F(LoggerBench_Blackhole, GetLogger)->Threads(1)->Threads(16); 114BENCHMARK_REGISTER_F(LoggerBench, LogToLoggerWithDisabledLogLevel) 115 ->Threads(1) 116 ->Threads(16); 117BENCHMARK_REGISTER_F(LoggerBench, LogToLoggerWithEnabledLogLevel) 118 ->Threads(1) 119 ->Threads(16); 120 121int main(int argc, char** argv) { 122 ::benchmark::Initialize(&argc, argv); 123 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { 124 return EXIT_FAILURE; 125 } 126 ::benchmark::RunSpecifiedBenchmarks(); 127 return EXIT_SUCCESS; 128} 129