1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <vector>
17 #include "benchmark/benchmark.h"
18 #include "logd/LogEvent.h"
19 #include "stats_event.h"
20 
21 namespace android {
22 namespace os {
23 namespace statsd {
24 
writeEventTestFields(AStatsEvent & event)25 static void writeEventTestFields(AStatsEvent& event) {
26     AStatsEvent_writeInt64(&event, 3L);
27     AStatsEvent_writeInt32(&event, 2);
28     AStatsEvent_writeFloat(&event, 2.0);
29     AStatsEvent_writeString(&event, "DemoStringValue");
30 }
31 
createStatsEvent(uint8_t * msg,int numElements=1)32 static size_t createStatsEvent(uint8_t* msg, int numElements = 1) {
33     AStatsEvent* event = AStatsEvent_obtain();
34     AStatsEvent_setAtomId(event, 100);
35     for (int i = 0; i < numElements; i++) {
36         writeEventTestFields(*event);
37     }
38     AStatsEvent_build(event);
39 
40     size_t size;
41     uint8_t* buf = AStatsEvent_getBuffer(event, &size);
42     memcpy(msg, buf, size);
43     return size;
44 }
45 
createStatsEventMedium(uint8_t * msg)46 static size_t createStatsEventMedium(uint8_t* msg) {
47     return createStatsEvent(msg, 5);
48 }
49 
createStatsEventLarge(uint8_t * msg)50 static size_t createStatsEventLarge(uint8_t* msg) {
51     return createStatsEvent(msg, 10);
52 }
53 
createStatsEventExtraLarge(uint8_t * msg)54 static size_t createStatsEventExtraLarge(uint8_t* msg) {
55     return createStatsEvent(msg, 20);
56 }
57 
BM_LogEventCreation(benchmark::State & state)58 static void BM_LogEventCreation(benchmark::State& state) {
59     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
60     const size_t size = createStatsEvent(msg);
61     while (state.KeepRunning()) {
62         LogEvent event(/*uid=*/ 1000, /*pid=*/ 1001);
63         benchmark::DoNotOptimize(event.parseBuffer(msg, size));
64     }
65 }
66 BENCHMARK(BM_LogEventCreation);
67 
BM_LogEventCreationWithPrefetch(benchmark::State & state)68 static void BM_LogEventCreationWithPrefetch(benchmark::State& state) {
69     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
70     const size_t size = createStatsEvent(msg);
71     while (state.KeepRunning()) {
72         LogEvent event(/*uid=*/1000, /*pid=*/1001);
73 
74         // explicitly parse header first
75         const LogEvent::BodyBufferInfo header = event.parseHeader(msg, size);
76 
77         // explicitly parse body using the header
78         benchmark::DoNotOptimize(event.parseBody(header));
79     }
80 }
81 BENCHMARK(BM_LogEventCreationWithPrefetch);
82 
BM_LogEventCreationWithPrefetchOnly(benchmark::State & state)83 static void BM_LogEventCreationWithPrefetchOnly(benchmark::State& state) {
84     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
85     const size_t size = createStatsEvent(msg);
86     while (state.KeepRunning()) {
87         LogEvent event(/*uid=*/1000, /*pid=*/1001);
88 
89         // explicitly parse header only and skip the body
90         benchmark::DoNotOptimize(event.parseHeader(msg, size));
91     }
92 }
93 BENCHMARK(BM_LogEventCreationWithPrefetchOnly);
94 
BM_LogEventCreationMedium(benchmark::State & state)95 static void BM_LogEventCreationMedium(benchmark::State& state) {
96     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
97     const size_t size = createStatsEventMedium(msg);
98     while (state.KeepRunning()) {
99         LogEvent event(/*uid=*/1000, /*pid=*/1001);
100 
101         benchmark::DoNotOptimize(event.parseBuffer(msg, size));
102     }
103 }
104 BENCHMARK(BM_LogEventCreationMedium);
105 
BM_LogEventCreationMediumWithPrefetch(benchmark::State & state)106 static void BM_LogEventCreationMediumWithPrefetch(benchmark::State& state) {
107     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
108     const size_t size = createStatsEventMedium(msg);
109     while (state.KeepRunning()) {
110         LogEvent event(/*uid=*/1000, /*pid=*/1001);
111 
112         // explicitly parse header first
113         const LogEvent::BodyBufferInfo header = event.parseHeader(msg, size);
114 
115         // explicitly parse body using the header
116         benchmark::DoNotOptimize(event.parseBody(header));
117     }
118 }
119 BENCHMARK(BM_LogEventCreationMediumWithPrefetch);
120 
BM_LogEventCreationMediumWithPrefetchOnly(benchmark::State & state)121 static void BM_LogEventCreationMediumWithPrefetchOnly(benchmark::State& state) {
122     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
123     const size_t size = createStatsEventMedium(msg);
124     while (state.KeepRunning()) {
125         LogEvent event(/*uid=*/1000, /*pid=*/1001);
126 
127         // explicitly parse header only and skip the body
128         benchmark::DoNotOptimize(event.parseHeader(msg, size));
129     }
130 }
131 BENCHMARK(BM_LogEventCreationMediumWithPrefetchOnly);
132 
BM_LogEventCreationLarge(benchmark::State & state)133 static void BM_LogEventCreationLarge(benchmark::State& state) {
134     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
135     const size_t size = createStatsEventLarge(msg);
136     while (state.KeepRunning()) {
137         LogEvent event(/*uid=*/1000, /*pid=*/1001);
138 
139         benchmark::DoNotOptimize(event.parseBuffer(msg, size));
140     }
141 }
142 BENCHMARK(BM_LogEventCreationLarge);
143 
BM_LogEventCreationLargeWithPrefetch(benchmark::State & state)144 static void BM_LogEventCreationLargeWithPrefetch(benchmark::State& state) {
145     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
146     const size_t size = createStatsEventLarge(msg);
147     while (state.KeepRunning()) {
148         LogEvent event(/*uid=*/1000, /*pid=*/1001);
149 
150         // explicitly parse header first
151         const LogEvent::BodyBufferInfo header = event.parseHeader(msg, size);
152 
153         // explicitly parse body using the header
154         benchmark::DoNotOptimize(event.parseBody(header));
155     }
156 }
157 BENCHMARK(BM_LogEventCreationLargeWithPrefetch);
158 
BM_LogEventCreationLargeWithPrefetchOnly(benchmark::State & state)159 static void BM_LogEventCreationLargeWithPrefetchOnly(benchmark::State& state) {
160     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
161     const size_t size = createStatsEventLarge(msg);
162     while (state.KeepRunning()) {
163         LogEvent event(/*uid=*/1000, /*pid=*/1001);
164 
165         // explicitly parse header only and skip the body
166         benchmark::DoNotOptimize(event.parseHeader(msg, size));
167     }
168 }
169 BENCHMARK(BM_LogEventCreationLargeWithPrefetchOnly);
170 
BM_LogEventCreationExtraLarge(benchmark::State & state)171 static void BM_LogEventCreationExtraLarge(benchmark::State& state) {
172     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
173     const size_t size = createStatsEventExtraLarge(msg);
174     while (state.KeepRunning()) {
175         LogEvent event(/*uid=*/1000, /*pid=*/1001);
176 
177         benchmark::DoNotOptimize(event.parseBuffer(msg, size));
178     }
179 }
180 BENCHMARK(BM_LogEventCreationExtraLarge);
181 
BM_LogEventCreationExtraLargeWithPrefetch(benchmark::State & state)182 static void BM_LogEventCreationExtraLargeWithPrefetch(benchmark::State& state) {
183     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
184     const size_t size = createStatsEventExtraLarge(msg);
185     while (state.KeepRunning()) {
186         LogEvent event(/*uid=*/1000, /*pid=*/1001);
187 
188         // explicitly parse header first
189         const LogEvent::BodyBufferInfo header = event.parseHeader(msg, size);
190 
191         // explicitly parse body using the header
192         benchmark::DoNotOptimize(event.parseBody(header));
193     }
194 }
195 BENCHMARK(BM_LogEventCreationExtraLargeWithPrefetch);
196 
BM_LogEventCreationExtraLargeWithPrefetchOnly(benchmark::State & state)197 static void BM_LogEventCreationExtraLargeWithPrefetchOnly(benchmark::State& state) {
198     uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
199     const size_t size = createStatsEventExtraLarge(msg);
200     while (state.KeepRunning()) {
201         LogEvent event(/*uid=*/1000, /*pid=*/1001);
202 
203         // explicitly parse header only and skip the body
204         benchmark::DoNotOptimize(event.parseHeader(msg, size));
205     }
206 }
207 BENCHMARK(BM_LogEventCreationExtraLargeWithPrefetchOnly);
208 
209 }  //  namespace statsd
210 }  //  namespace os
211 }  //  namespace android
212