• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "FieldValue.h"
19 #include "HashableDimensionKey.h"
20 #include "logd/LogEvent.h"
21 #include "stats_log_util.h"
22 #include "metric_util.h"
23 
24 namespace android {
25 namespace os {
26 namespace statsd {
27 
28 using std::vector;
29 
CreateDurationMetricConfig_NoLink_AND_CombinationCondition(DurationMetric::AggregationType aggregationType,bool addExtraDimensionInCondition)30 static StatsdConfig CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
31         DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
32     StatsdConfig config;
33     *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
34     *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
35     *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
36     *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
37     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
38     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
39 
40     auto scheduledJobPredicate = CreateScheduledJobPredicate();
41     auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
42     dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
43     dimensions->add_child()->set_field(2);  // job name field.
44 
45     auto screenIsOffPredicate = CreateScreenIsOffPredicate();
46 
47     auto isSyncingPredicate = CreateIsSyncingPredicate();
48     auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
49     *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
50                                                           {Position::FIRST});
51     if (addExtraDimensionInCondition) {
52         syncDimension->add_child()->set_field(2 /* name field*/);
53     }
54 
55     *config.add_predicate() = scheduledJobPredicate;
56     *config.add_predicate() = screenIsOffPredicate;
57     *config.add_predicate() = isSyncingPredicate;
58     auto combinationPredicate = config.add_predicate();
59     combinationPredicate->set_id(StringToId("CombinationPredicate"));
60     combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
61     addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
62     addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
63 
64     auto metric = config.add_duration_metric();
65     metric->set_bucket(FIVE_MINUTES);
66     metric->set_id(StringToId("scheduledJob"));
67     metric->set_what(scheduledJobPredicate.id());
68     metric->set_condition(combinationPredicate->id());
69     metric->set_aggregation_type(aggregationType);
70     auto dimensionWhat = metric->mutable_dimensions_in_what();
71     dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
72     dimensionWhat->add_child()->set_field(2);  // job name field.
73     *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
74             android::util::SYNC_STATE_CHANGED, {Position::FIRST});
75     return config;
76 }
77 
CreateDurationMetricConfig_Link_AND_CombinationCondition(DurationMetric::AggregationType aggregationType,bool addExtraDimensionInCondition)78 static StatsdConfig CreateDurationMetricConfig_Link_AND_CombinationCondition(
79         DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
80     StatsdConfig config;
81     *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
82     *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
83     *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
84     *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
85     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
86     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
87 
88     auto scheduledJobPredicate = CreateScheduledJobPredicate();
89     auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
90     *dimensions = CreateAttributionUidDimensions(
91                 android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
92     dimensions->add_child()->set_field(2);  // job name field.
93 
94     auto isSyncingPredicate = CreateIsSyncingPredicate();
95     auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
96     *syncDimension = CreateAttributionUidDimensions(
97             android::util::SYNC_STATE_CHANGED, {Position::FIRST});
98     if (addExtraDimensionInCondition) {
99         syncDimension->add_child()->set_field(2 /* name field*/);
100     }
101 
102     auto screenIsOffPredicate = CreateScreenIsOffPredicate();
103 
104     *config.add_predicate() = scheduledJobPredicate;
105     *config.add_predicate() = screenIsOffPredicate;
106     *config.add_predicate() = isSyncingPredicate;
107     auto combinationPredicate = config.add_predicate();
108     combinationPredicate->set_id(StringToId("CombinationPredicate"));
109     combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
110     addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
111     addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
112 
113     auto metric = config.add_duration_metric();
114     metric->set_bucket(FIVE_MINUTES);
115     metric->set_id(StringToId("scheduledJob"));
116     metric->set_what(scheduledJobPredicate.id());
117     metric->set_condition(combinationPredicate->id());
118     metric->set_aggregation_type(aggregationType);
119     *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
120             android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
121 
122     auto links = metric->add_links();
123     links->set_condition(isSyncingPredicate.id());
124     *links->mutable_fields_in_what() =
125             CreateAttributionUidDimensions(
126                 android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
127     *links->mutable_fields_in_condition() =
128             CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
129     return config;
130 }
131 
BM_DurationMetricNoLink(benchmark::State & state)132 static void BM_DurationMetricNoLink(benchmark::State& state) {
133     ConfigKey cfgKey;
134     auto config = CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
135             DurationMetric::SUM, false);
136     int64_t bucketStartTimeNs = 10000000000;
137     int64_t bucketSizeNs =
138             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
139 
140 
141     std::vector<AttributionNodeInternal> attributions1 = {
142             CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
143             CreateAttribution(222, "GMSCoreModule2")};
144 
145     std::vector<AttributionNodeInternal> attributions2 = {
146             CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
147             CreateAttribution(555, "GMSCoreModule2")};
148 
149     std::vector<std::unique_ptr<LogEvent>> events;
150 
151     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
152                                                    bucketStartTimeNs + 11));
153     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
154                                                    bucketStartTimeNs + 40));
155 
156     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
157                                                    bucketStartTimeNs + 102));
158     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
159                                                    bucketStartTimeNs + 450));
160 
161     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
162                                                    bucketStartTimeNs + 650));
163     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
164                                                    bucketStartTimeNs + bucketSizeNs + 100));
165 
166     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
167                                                    bucketStartTimeNs + bucketSizeNs + 640));
168     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
169                                                    bucketStartTimeNs + bucketSizeNs + 650));
170 
171     events.push_back(CreateStartScheduledJobEvent(
172             {CreateAttribution(9999, "")}, "job0", bucketStartTimeNs + 2));
173     events.push_back(CreateFinishScheduledJobEvent(
174             {CreateAttribution(9999, "")}, "job0",bucketStartTimeNs + 101));
175 
176     events.push_back(CreateStartScheduledJobEvent(
177             {CreateAttribution(9999, "")}, "job2", bucketStartTimeNs + 201));
178     events.push_back(CreateFinishScheduledJobEvent(
179             {CreateAttribution(9999, "")}, "job2",bucketStartTimeNs + 500));
180 
181     events.push_back(CreateStartScheduledJobEvent(
182             {CreateAttribution(8888, "")}, "job2", bucketStartTimeNs + 600));
183     events.push_back(CreateFinishScheduledJobEvent(
184             {CreateAttribution(8888, "")}, "job2",bucketStartTimeNs + bucketSizeNs + 850));
185 
186     events.push_back(CreateStartScheduledJobEvent(
187             {CreateAttribution(8888, "")}, "job1", bucketStartTimeNs + bucketSizeNs + 600));
188     events.push_back(CreateFinishScheduledJobEvent(
189             {CreateAttribution(8888, "")}, "job1", bucketStartTimeNs + bucketSizeNs + 900));
190 
191     events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
192                                           bucketStartTimeNs + 10));
193     events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
194                                         bucketStartTimeNs + 50));
195 
196     events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
197                                           bucketStartTimeNs + 200));
198     events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
199                                         bucketStartTimeNs + bucketSizeNs + 300));
200 
201     events.push_back(CreateSyncStartEvent(attributions1, "ReadDoc",
202                                           bucketStartTimeNs + 400));
203     events.push_back(CreateSyncEndEvent(attributions1, "ReadDoc",
204                                         bucketStartTimeNs + bucketSizeNs - 1));
205 
206     events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
207                                           bucketStartTimeNs + 401));
208     events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
209                                         bucketStartTimeNs + bucketSizeNs + 700));
210 
211     sortLogEventsByTimestamp(&events);
212 
213     while (state.KeepRunning()) {
214         auto processor = CreateStatsLogProcessor(
215                 bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
216         for (const auto& event : events) {
217             processor->OnLogEvent(event.get());
218         }
219     }
220 }
221 
222 BENCHMARK(BM_DurationMetricNoLink);
223 
224 
BM_DurationMetricLink(benchmark::State & state)225 static void BM_DurationMetricLink(benchmark::State& state) {
226     ConfigKey cfgKey;
227     auto config = CreateDurationMetricConfig_Link_AND_CombinationCondition(
228         DurationMetric::SUM, false);
229     int64_t bucketStartTimeNs = 10000000000;
230     int64_t bucketSizeNs =
231             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
232 
233     std::vector<AttributionNodeInternal> attributions1 = {
234             CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
235             CreateAttribution(222, "GMSCoreModule2")};
236 
237     std::vector<AttributionNodeInternal> attributions2 = {
238             CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
239             CreateAttribution(555, "GMSCoreModule2")};
240 
241     std::vector<AttributionNodeInternal> attributions3 = {
242             CreateAttribution(444, "App3"), CreateAttribution(222, "GMSCoreModule1"),
243             CreateAttribution(555, "GMSCoreModule2")};
244 
245     std::vector<std::unique_ptr<LogEvent>> events;
246 
247     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
248                                                    bucketStartTimeNs + 55));
249     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
250                                                    bucketStartTimeNs + 120));
251     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
252                                                    bucketStartTimeNs + 121));
253     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
254                                                    bucketStartTimeNs + 450));
255 
256     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF,
257                                                    bucketStartTimeNs + 501));
258     events.push_back(CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
259                                                    bucketStartTimeNs + bucketSizeNs + 100));
260 
261     events.push_back(CreateStartScheduledJobEvent(
262             {CreateAttribution(111, "App1")}, "job1", bucketStartTimeNs + 1));
263     events.push_back(CreateFinishScheduledJobEvent(
264             {CreateAttribution(111, "App1")}, "job1",bucketStartTimeNs + 101));
265 
266     events.push_back(CreateStartScheduledJobEvent(
267             {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 201));
268     events.push_back(CreateFinishScheduledJobEvent(
269             {CreateAttribution(333, "App2")}, "job2",bucketStartTimeNs + 500));
270     events.push_back(CreateStartScheduledJobEvent(
271             {CreateAttribution(333, "App2")}, "job2", bucketStartTimeNs + 600));
272     events.push_back(CreateFinishScheduledJobEvent(
273             {CreateAttribution(333, "App2")}, "job2",
274             bucketStartTimeNs + bucketSizeNs + 850));
275 
276     events.push_back(
277         CreateStartScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
278                                      bucketStartTimeNs + bucketSizeNs - 2));
279     events.push_back(
280         CreateFinishScheduledJobEvent({CreateAttribution(444, "App3")}, "job3",
281                                       bucketStartTimeNs + bucketSizeNs + 900));
282 
283     events.push_back(CreateSyncStartEvent(attributions1, "ReadEmail",
284                                           bucketStartTimeNs + 50));
285     events.push_back(CreateSyncEndEvent(attributions1, "ReadEmail",
286                                         bucketStartTimeNs + 110));
287 
288     events.push_back(CreateSyncStartEvent(attributions2, "ReadEmail",
289                                           bucketStartTimeNs + 300));
290     events.push_back(CreateSyncEndEvent(attributions2, "ReadEmail",
291                                         bucketStartTimeNs + bucketSizeNs + 700));
292     events.push_back(CreateSyncStartEvent(attributions2, "ReadDoc",
293                                           bucketStartTimeNs + 400));
294     events.push_back(CreateSyncEndEvent(attributions2, "ReadDoc",
295                                         bucketStartTimeNs + bucketSizeNs - 1));
296 
297     events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
298                                           bucketStartTimeNs + 550));
299     events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
300                                         bucketStartTimeNs + 800));
301     events.push_back(CreateSyncStartEvent(attributions3, "ReadDoc",
302                                           bucketStartTimeNs + bucketSizeNs - 1));
303     events.push_back(CreateSyncEndEvent(attributions3, "ReadDoc",
304                                         bucketStartTimeNs + bucketSizeNs + 700));
305     sortLogEventsByTimestamp(&events);
306 
307     while (state.KeepRunning()) {
308         auto processor = CreateStatsLogProcessor(
309                 bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
310         for (const auto& event : events) {
311             processor->OnLogEvent(event.get());
312         }
313     }
314 }
315 
316 BENCHMARK(BM_DurationMetricLink);
317 
318 }  //  namespace statsd
319 }  //  namespace os
320 }  //  namespace android
321