• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 
17 #include "benchmark/benchmark.h"
18 
19 #include "android-base/stringprintf.h"
20 #include "androidfw/ApkAssets.h"
21 #include "androidfw/AssetManager.h"
22 #include "androidfw/AssetManager2.h"
23 #include "androidfw/ResourceTypes.h"
24 
25 #include "BenchmarkHelpers.h"
26 #include "TestHelpers.h"
27 #include "data/basic/R.h"
28 #include "data/libclient/R.h"
29 #include "data/styles/R.h"
30 
31 namespace app = com::android::app;
32 namespace basic = com::android::basic;
33 namespace libclient = com::android::libclient;
34 
35 namespace android {
36 
37 constexpr const static char* kFrameworkPath = "/system/framework/framework-res.apk";
38 
BM_AssetManagerLoadAssets(benchmark::State & state)39 static void BM_AssetManagerLoadAssets(benchmark::State& state) {
40   std::string path = GetTestDataPath() + "/basic/basic.apk";
41   while (state.KeepRunning()) {
42     std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
43     AssetManager2 assets;
44     assets.SetApkAssets({apk.get()});
45   }
46 }
47 BENCHMARK(BM_AssetManagerLoadAssets);
48 
BM_AssetManagerLoadAssetsOld(benchmark::State & state)49 static void BM_AssetManagerLoadAssetsOld(benchmark::State& state) {
50   String8 path((GetTestDataPath() + "/basic/basic.apk").data());
51   while (state.KeepRunning()) {
52     AssetManager assets;
53     assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */,
54                         false /* isSystemAsset */);
55 
56     // Force creation.
57     assets.getResources(true);
58   }
59 }
60 BENCHMARK(BM_AssetManagerLoadAssetsOld);
61 
BM_AssetManagerLoadFrameworkAssets(benchmark::State & state)62 static void BM_AssetManagerLoadFrameworkAssets(benchmark::State& state) {
63   std::string path = kFrameworkPath;
64   while (state.KeepRunning()) {
65     std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
66     AssetManager2 assets;
67     assets.SetApkAssets({apk.get()});
68   }
69 }
70 BENCHMARK(BM_AssetManagerLoadFrameworkAssets);
71 
BM_AssetManagerLoadFrameworkAssetsOld(benchmark::State & state)72 static void BM_AssetManagerLoadFrameworkAssetsOld(benchmark::State& state) {
73   String8 path(kFrameworkPath);
74   while (state.KeepRunning()) {
75     AssetManager assets;
76     assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */,
77                         false /* isSystemAsset */);
78 
79     // Force creation.
80     assets.getResources(true);
81   }
82 }
83 BENCHMARK(BM_AssetManagerLoadFrameworkAssetsOld);
84 
GetResourceBenchmark(const std::vector<std::string> & paths,const ResTable_config * config,uint32_t resid,benchmark::State & state)85 static void GetResourceBenchmark(const std::vector<std::string>& paths,
86                                  const ResTable_config* config, uint32_t resid,
87                                  benchmark::State& state) {
88   std::vector<std::unique_ptr<const ApkAssets>> apk_assets;
89   std::vector<const ApkAssets*> apk_assets_ptrs;
90   for (const std::string& path : paths) {
91     std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
92     if (apk == nullptr) {
93       state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str());
94       return;
95     }
96     apk_assets_ptrs.push_back(apk.get());
97     apk_assets.push_back(std::move(apk));
98   }
99 
100   AssetManager2 assetmanager;
101   assetmanager.SetApkAssets(apk_assets_ptrs);
102   if (config != nullptr) {
103     assetmanager.SetConfiguration(*config);
104   }
105 
106   Res_value value;
107   ResTable_config selected_config;
108   uint32_t flags;
109 
110   while (state.KeepRunning()) {
111     assetmanager.GetResource(resid, false /* may_be_bag */, 0u /* density_override */, &value,
112                              &selected_config, &flags);
113   }
114 }
115 
BM_AssetManagerGetResource(benchmark::State & state)116 static void BM_AssetManagerGetResource(benchmark::State& state) {
117   GetResourceBenchmark({GetTestDataPath() + "/basic/basic.apk"}, nullptr /*config*/,
118                        basic::R::integer::number1, state);
119 }
120 BENCHMARK(BM_AssetManagerGetResource);
121 
BM_AssetManagerGetResourceOld(benchmark::State & state)122 static void BM_AssetManagerGetResourceOld(benchmark::State& state) {
123   GetResourceBenchmarkOld({GetTestDataPath() + "/basic/basic.apk"}, nullptr /*config*/,
124                           basic::R::integer::number1, state);
125 }
126 BENCHMARK(BM_AssetManagerGetResourceOld);
127 
BM_AssetManagerGetLibraryResource(benchmark::State & state)128 static void BM_AssetManagerGetLibraryResource(benchmark::State& state) {
129   GetResourceBenchmark(
130       {GetTestDataPath() + "/lib_two/lib_two.apk", GetTestDataPath() + "/lib_one/lib_one.apk",
131        GetTestDataPath() + "/libclient/libclient.apk"},
132       nullptr /*config*/, libclient::R::string::foo_one, state);
133 }
134 BENCHMARK(BM_AssetManagerGetLibraryResource);
135 
BM_AssetManagerGetLibraryResourceOld(benchmark::State & state)136 static void BM_AssetManagerGetLibraryResourceOld(benchmark::State& state) {
137   GetResourceBenchmarkOld(
138       {GetTestDataPath() + "/lib_two/lib_two.apk", GetTestDataPath() + "/lib_one/lib_one.apk",
139        GetTestDataPath() + "/libclient/libclient.apk"},
140       nullptr /*config*/, libclient::R::string::foo_one, state);
141 }
142 BENCHMARK(BM_AssetManagerGetLibraryResourceOld);
143 
144 constexpr static const uint32_t kStringOkId = 0x0104000au;
145 
BM_AssetManagerGetResourceFrameworkLocale(benchmark::State & state)146 static void BM_AssetManagerGetResourceFrameworkLocale(benchmark::State& state) {
147   ResTable_config config;
148   memset(&config, 0, sizeof(config));
149   memcpy(config.language, "fr", 2);
150   GetResourceBenchmark({kFrameworkPath}, &config, kStringOkId, state);
151 }
152 BENCHMARK(BM_AssetManagerGetResourceFrameworkLocale);
153 
BM_AssetManagerGetResourceFrameworkLocaleOld(benchmark::State & state)154 static void BM_AssetManagerGetResourceFrameworkLocaleOld(benchmark::State& state) {
155   ResTable_config config;
156   memset(&config, 0, sizeof(config));
157   memcpy(config.language, "fr", 2);
158   GetResourceBenchmarkOld({kFrameworkPath}, &config, kStringOkId, state);
159 }
160 BENCHMARK(BM_AssetManagerGetResourceFrameworkLocaleOld);
161 
BM_AssetManagerGetBag(benchmark::State & state)162 static void BM_AssetManagerGetBag(benchmark::State& state) {
163   std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
164   if (apk == nullptr) {
165     state.SkipWithError("Failed to load assets");
166     return;
167   }
168 
169   AssetManager2 assets;
170   assets.SetApkAssets({apk.get()});
171 
172   while (state.KeepRunning()) {
173     const ResolvedBag* bag = assets.GetBag(app::R::style::StyleTwo);
174     const auto bag_end = end(bag);
175     for (auto iter = begin(bag); iter != bag_end; ++iter) {
176       uint32_t key = iter->key;
177       Res_value value = iter->value;
178       benchmark::DoNotOptimize(key);
179       benchmark::DoNotOptimize(value);
180     }
181   }
182 }
183 BENCHMARK(BM_AssetManagerGetBag);
184 
BM_AssetManagerGetBagOld(benchmark::State & state)185 static void BM_AssetManagerGetBagOld(benchmark::State& state) {
186   AssetManager assets;
187   if (!assets.addAssetPath(String8((GetTestDataPath() + "/styles/styles.apk").data()),
188                            nullptr /*cookie*/, false /*appAsLib*/, false /*isSystemAssets*/)) {
189     state.SkipWithError("Failed to load assets");
190     return;
191   }
192 
193   const ResTable& table = assets.getResources(true);
194 
195   while (state.KeepRunning()) {
196     const ResTable::bag_entry* bag_begin;
197     const ssize_t N = table.lockBag(app::R::style::StyleTwo, &bag_begin);
198     const ResTable::bag_entry* const bag_end = bag_begin + N;
199     for (auto iter = bag_begin; iter != bag_end; ++iter) {
200       uint32_t key = iter->map.name.ident;
201       Res_value value = iter->map.value;
202       benchmark::DoNotOptimize(key);
203       benchmark::DoNotOptimize(value);
204     }
205     table.unlockBag(bag_begin);
206   }
207 }
208 BENCHMARK(BM_AssetManagerGetBagOld);
209 
BM_AssetManagerGetResourceLocales(benchmark::State & state)210 static void BM_AssetManagerGetResourceLocales(benchmark::State& state) {
211   std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
212   if (apk == nullptr) {
213     state.SkipWithError("Failed to load assets");
214     return;
215   }
216 
217   AssetManager2 assets;
218   assets.SetApkAssets({apk.get()});
219 
220   while (state.KeepRunning()) {
221     std::set<std::string> locales =
222         assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/);
223     benchmark::DoNotOptimize(locales);
224   }
225 }
226 BENCHMARK(BM_AssetManagerGetResourceLocales);
227 
BM_AssetManagerGetResourceLocalesOld(benchmark::State & state)228 static void BM_AssetManagerGetResourceLocalesOld(benchmark::State& state) {
229   AssetManager assets;
230   if (!assets.addAssetPath(String8(kFrameworkPath), nullptr /*cookie*/, false /*appAsLib*/,
231                            false /*isSystemAssets*/)) {
232     state.SkipWithError("Failed to load assets");
233     return;
234   }
235 
236   const ResTable& table = assets.getResources(true);
237 
238   while (state.KeepRunning()) {
239     Vector<String8> locales;
240     table.getLocales(&locales, true /*includeSystemLocales*/, true /*mergeEquivalentLangs*/);
241     benchmark::DoNotOptimize(locales);
242   }
243 }
244 BENCHMARK(BM_AssetManagerGetResourceLocalesOld);
245 
246 }  // namespace android
247