Home | History | Annotate | Download | only in benchmark
      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 
     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 
     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 
    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 
    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