1 // Copyright 2022 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/base/attributes.h"
16 #include "absl/base/log_severity.h"
17 #include "absl/flags/flag.h"
18 #include "absl/log/check.h"
19 #include "absl/log/globals.h"
20 #include "absl/log/internal/flags.h"
21 #include "absl/log/log.h"
22 #include "absl/log/log_entry.h"
23 #include "absl/log/log_sink.h"
24 #include "absl/log/log_sink_registry.h"
25 #include "absl/log/vlog_is_on.h"
26 #include "benchmark/benchmark.h"
27
28 namespace {
29
30 class NullLogSink : public absl::LogSink {
31 public:
NullLogSink()32 NullLogSink() { absl::AddLogSink(this); }
33
~NullLogSink()34 ~NullLogSink() override { absl::RemoveLogSink(this); }
35
Send(const absl::LogEntry &)36 void Send(const absl::LogEntry&) override {}
37 };
38
39 constexpr int x = -1;
40
BM_SuccessfulBinaryCheck(benchmark::State & state)41 void BM_SuccessfulBinaryCheck(benchmark::State& state) {
42 int n = 0;
43 while (state.KeepRunningBatch(8)) {
44 CHECK_GE(n, x);
45 CHECK_GE(n, x);
46 CHECK_GE(n, x);
47 CHECK_GE(n, x);
48 CHECK_GE(n, x);
49 CHECK_GE(n, x);
50 CHECK_GE(n, x);
51 CHECK_GE(n, x);
52 ++n;
53 }
54 benchmark::DoNotOptimize(n);
55 }
56 BENCHMARK(BM_SuccessfulBinaryCheck);
57
BM_SuccessfulUnaryCheck(benchmark::State & state)58 static void BM_SuccessfulUnaryCheck(benchmark::State& state) {
59 int n = 0;
60 while (state.KeepRunningBatch(8)) {
61 CHECK(n >= x);
62 CHECK(n >= x);
63 CHECK(n >= x);
64 CHECK(n >= x);
65 CHECK(n >= x);
66 CHECK(n >= x);
67 CHECK(n >= x);
68 CHECK(n >= x);
69 ++n;
70 }
71 benchmark::DoNotOptimize(n);
72 }
73 BENCHMARK(BM_SuccessfulUnaryCheck);
74
BM_DisabledLogOverhead(benchmark::State & state)75 static void BM_DisabledLogOverhead(benchmark::State& state) {
76 absl::ScopedStderrThreshold disable_stderr_logging(
77 absl::LogSeverityAtLeast::kInfinity);
78 absl::log_internal::ScopedMinLogLevel scoped_min_log_level(
79 absl::LogSeverityAtLeast::kInfinity);
80 for (auto _ : state) {
81 LOG(INFO);
82 }
83 }
84 BENCHMARK(BM_DisabledLogOverhead);
85
BM_EnabledLogOverhead(benchmark::State & state)86 static void BM_EnabledLogOverhead(benchmark::State& state) {
87 absl::ScopedStderrThreshold stderr_logging(
88 absl::LogSeverityAtLeast::kInfinity);
89 absl::log_internal::ScopedMinLogLevel scoped_min_log_level(
90 absl::LogSeverityAtLeast::kInfo);
91 ABSL_ATTRIBUTE_UNUSED NullLogSink null_sink;
92 for (auto _ : state) {
93 LOG(INFO);
94 }
95 }
96 BENCHMARK(BM_EnabledLogOverhead);
97
BM_VlogIsOnOverhead(benchmark::State & state)98 static void BM_VlogIsOnOverhead(benchmark::State& state) {
99 // It would make sense to do this only when state.thread_index == 0,
100 // but thread_index is an int on some platforms (e.g. Android) and a
101 // function returning an int on others. So we just do it on all threads.
102 // TODO(b/152609127): set only if thread_index == 0.
103 absl::SetFlag(&FLAGS_v, 0);
104
105 while (state.KeepRunningBatch(10)) {
106 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 1
107 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 2
108 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 3
109 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 4
110 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 5
111 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 6
112 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 7
113 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 8
114 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 9
115 benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 10
116 }
117 }
118 BENCHMARK(BM_VlogIsOnOverhead)->ThreadRange(1, 64);
119
BM_VlogIsNotOnOverhead(benchmark::State & state)120 static void BM_VlogIsNotOnOverhead(benchmark::State& state) {
121 // It would make sense to do this only when state.thread_index == 0,
122 // but thread_index is an int on some platforms (e.g. Android) and a
123 // function returning an int on others. So we just do it on all threads.
124 // TODO(b/152609127): set only if thread_index == 0.
125 absl::SetFlag(&FLAGS_v, 0);
126
127 while (state.KeepRunningBatch(10)) {
128 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 1
129 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 2
130 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 3
131 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 4
132 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 5
133 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 6
134 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 7
135 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 8
136 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 9
137 benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 10
138 }
139 }
140 BENCHMARK(BM_VlogIsNotOnOverhead)->ThreadRange(1, 64);
141
BM_LogEveryNOverhead(benchmark::State & state)142 static void BM_LogEveryNOverhead(benchmark::State& state) {
143 absl::ScopedStderrThreshold disable_stderr_logging(
144 absl::LogSeverityAtLeast::kInfinity);
145 absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfinity);
146 ABSL_ATTRIBUTE_UNUSED NullLogSink null_sink;
147
148 while (state.KeepRunningBatch(10)) {
149 LOG_EVERY_N_SEC(INFO, 10);
150 LOG_EVERY_N_SEC(INFO, 20);
151 LOG_EVERY_N_SEC(INFO, 30);
152 LOG_EVERY_N_SEC(INFO, 40);
153 LOG_EVERY_N_SEC(INFO, 50);
154 LOG_EVERY_N_SEC(INFO, 60);
155 LOG_EVERY_N_SEC(INFO, 70);
156 LOG_EVERY_N_SEC(INFO, 80);
157 LOG_EVERY_N_SEC(INFO, 90);
158 LOG_EVERY_N_SEC(INFO, 100);
159 }
160 }
161 BENCHMARK(BM_LogEveryNOverhead)->ThreadRange(1, 64);
162
163 } // namespace
164
165