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