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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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