|  | /* | 
|  | * Copyright (C) 2016 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #include "benchmark/benchmark.h" | 
|  |  | 
|  | #include "android-base/stringprintf.h" | 
|  | #include "androidfw/ApkAssets.h" | 
|  | #include "androidfw/AssetManager.h" | 
|  | #include "androidfw/AssetManager2.h" | 
|  | #include "androidfw/ResourceTypes.h" | 
|  |  | 
|  | #include "BenchmarkHelpers.h" | 
|  | #include "data/basic/R.h" | 
|  | #include "data/libclient/R.h" | 
|  | #include "data/styles/R.h" | 
|  |  | 
|  | namespace app = com::android::app; | 
|  | namespace basic = com::android::basic; | 
|  | namespace libclient = com::android::libclient; | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | constexpr const static char* kFrameworkPath = "/system/framework/framework-res.apk"; | 
|  |  | 
|  | static void BM_AssetManagerLoadAssets(benchmark::State& state) { | 
|  | std::string path = GetTestDataPath() + "/basic/basic.apk"; | 
|  | while (state.KeepRunning()) { | 
|  | std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path); | 
|  | AssetManager2 assets; | 
|  | assets.SetApkAssets({apk.get()}); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerLoadAssets); | 
|  |  | 
|  | static void BM_AssetManagerLoadAssetsOld(benchmark::State& state) { | 
|  | String8 path((GetTestDataPath() + "/basic/basic.apk").data()); | 
|  | while (state.KeepRunning()) { | 
|  | AssetManager assets; | 
|  | assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */, | 
|  | false /* isSystemAsset */); | 
|  |  | 
|  | // Force creation. | 
|  | assets.getResources(true); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerLoadAssetsOld); | 
|  |  | 
|  | static void BM_AssetManagerLoadFrameworkAssets(benchmark::State& state) { | 
|  | std::string path = kFrameworkPath; | 
|  | while (state.KeepRunning()) { | 
|  | std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path); | 
|  | AssetManager2 assets; | 
|  | assets.SetApkAssets({apk.get()}); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerLoadFrameworkAssets); | 
|  |  | 
|  | static void BM_AssetManagerLoadFrameworkAssetsOld(benchmark::State& state) { | 
|  | String8 path(kFrameworkPath); | 
|  | while (state.KeepRunning()) { | 
|  | AssetManager assets; | 
|  | assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */, | 
|  | false /* isSystemAsset */); | 
|  |  | 
|  | // Force creation. | 
|  | assets.getResources(true); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerLoadFrameworkAssetsOld); | 
|  |  | 
|  | static void BM_AssetManagerGetResource(benchmark::State& state, uint32_t resid) { | 
|  | GetResourceBenchmark({GetTestDataPath() + "/basic/basic.apk"}, nullptr /*config*/, resid, state); | 
|  | } | 
|  | BENCHMARK_CAPTURE(BM_AssetManagerGetResource, number1, basic::R::integer::number1); | 
|  | BENCHMARK_CAPTURE(BM_AssetManagerGetResource, deep_ref, basic::R::integer::deep_ref); | 
|  |  | 
|  | static void BM_AssetManagerGetResourceOld(benchmark::State& state, uint32_t resid) { | 
|  | GetResourceBenchmarkOld({GetTestDataPath() + "/basic/basic.apk"}, nullptr /*config*/, resid, | 
|  | state); | 
|  | } | 
|  | BENCHMARK_CAPTURE(BM_AssetManagerGetResourceOld, number1, basic::R::integer::number1); | 
|  | BENCHMARK_CAPTURE(BM_AssetManagerGetResourceOld, deep_ref, basic::R::integer::deep_ref); | 
|  |  | 
|  | static void BM_AssetManagerGetLibraryResource(benchmark::State& state) { | 
|  | GetResourceBenchmark( | 
|  | {GetTestDataPath() + "/lib_two/lib_two.apk", GetTestDataPath() + "/lib_one/lib_one.apk", | 
|  | GetTestDataPath() + "/libclient/libclient.apk"}, | 
|  | nullptr /*config*/, libclient::R::string::foo_one, state); | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetLibraryResource); | 
|  |  | 
|  | static void BM_AssetManagerGetLibraryResourceOld(benchmark::State& state) { | 
|  | GetResourceBenchmarkOld( | 
|  | {GetTestDataPath() + "/lib_two/lib_two.apk", GetTestDataPath() + "/lib_one/lib_one.apk", | 
|  | GetTestDataPath() + "/libclient/libclient.apk"}, | 
|  | nullptr /*config*/, libclient::R::string::foo_one, state); | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetLibraryResourceOld); | 
|  |  | 
|  | constexpr static const uint32_t kStringOkId = 0x0104000au; | 
|  |  | 
|  | static void BM_AssetManagerGetResourceFrameworkLocale(benchmark::State& state) { | 
|  | ResTable_config config; | 
|  | memset(&config, 0, sizeof(config)); | 
|  | memcpy(config.language, "fr", 2); | 
|  | GetResourceBenchmark({kFrameworkPath}, &config, kStringOkId, state); | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetResourceFrameworkLocale); | 
|  |  | 
|  | static void BM_AssetManagerGetResourceFrameworkLocaleOld(benchmark::State& state) { | 
|  | ResTable_config config; | 
|  | memset(&config, 0, sizeof(config)); | 
|  | memcpy(config.language, "fr", 2); | 
|  | GetResourceBenchmarkOld({kFrameworkPath}, &config, kStringOkId, state); | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetResourceFrameworkLocaleOld); | 
|  |  | 
|  | static void BM_AssetManagerGetBag(benchmark::State& state) { | 
|  | std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); | 
|  | if (apk == nullptr) { | 
|  | state.SkipWithError("Failed to load assets"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | AssetManager2 assets; | 
|  | assets.SetApkAssets({apk.get()}); | 
|  |  | 
|  | while (state.KeepRunning()) { | 
|  | auto bag = assets.GetBag(app::R::style::StyleTwo); | 
|  | if (!bag.has_value()) { | 
|  | state.SkipWithError("Failed to load get bag"); | 
|  | return; | 
|  | } | 
|  | const auto bag_end = end(*bag); | 
|  | for (auto iter = begin(*bag); iter != bag_end; ++iter) { | 
|  | uint32_t key = iter->key; | 
|  | Res_value value = iter->value; | 
|  | benchmark::DoNotOptimize(key); | 
|  | benchmark::DoNotOptimize(value); | 
|  | } | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetBag); | 
|  |  | 
|  | static void BM_AssetManagerGetBagOld(benchmark::State& state) { | 
|  | AssetManager assets; | 
|  | if (!assets.addAssetPath(String8((GetTestDataPath() + "/styles/styles.apk").data()), | 
|  | nullptr /*cookie*/, false /*appAsLib*/, false /*isSystemAssets*/)) { | 
|  | state.SkipWithError("Failed to load assets"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | const ResTable& table = assets.getResources(true); | 
|  |  | 
|  | while (state.KeepRunning()) { | 
|  | const ResTable::bag_entry* bag_begin; | 
|  | const ssize_t N = table.lockBag(app::R::style::StyleTwo, &bag_begin); | 
|  | const ResTable::bag_entry* const bag_end = bag_begin + N; | 
|  | for (auto iter = bag_begin; iter != bag_end; ++iter) { | 
|  | uint32_t key = iter->map.name.ident; | 
|  | Res_value value = iter->map.value; | 
|  | benchmark::DoNotOptimize(key); | 
|  | benchmark::DoNotOptimize(value); | 
|  | } | 
|  | table.unlockBag(bag_begin); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetBagOld); | 
|  |  | 
|  | static void BM_AssetManagerGetResourceLocales(benchmark::State& state) { | 
|  | std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath); | 
|  | if (apk == nullptr) { | 
|  | state.SkipWithError("Failed to load assets"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | AssetManager2 assets; | 
|  | assets.SetApkAssets({apk.get()}); | 
|  |  | 
|  | while (state.KeepRunning()) { | 
|  | std::set<std::string> locales = | 
|  | assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/); | 
|  | benchmark::DoNotOptimize(locales); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetResourceLocales); | 
|  |  | 
|  | static void BM_AssetManagerGetResourceLocalesOld(benchmark::State& state) { | 
|  | AssetManager assets; | 
|  | if (!assets.addAssetPath(String8(kFrameworkPath), nullptr /*cookie*/, false /*appAsLib*/, | 
|  | true /*isSystemAssets*/)) { | 
|  | state.SkipWithError("Failed to load assets"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | const ResTable& table = assets.getResources(true); | 
|  |  | 
|  | while (state.KeepRunning()) { | 
|  | Vector<String8> locales; | 
|  | table.getLocales(&locales, true /*includeSystemLocales*/, true /*mergeEquivalentLangs*/); | 
|  | benchmark::DoNotOptimize(locales); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerGetResourceLocalesOld); | 
|  |  | 
|  | static void BM_AssetManagerSetConfigurationFramework(benchmark::State& state) { | 
|  | std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath); | 
|  | if (apk == nullptr) { | 
|  | state.SkipWithError("Failed to load assets"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | AssetManager2 assets; | 
|  | assets.SetApkAssets({apk.get()}); | 
|  |  | 
|  | ResTable_config config; | 
|  | memset(&config, 0, sizeof(config)); | 
|  |  | 
|  | while (state.KeepRunning()) { | 
|  | config.sdkVersion = ~config.sdkVersion; | 
|  | assets.SetConfiguration(config); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerSetConfigurationFramework); | 
|  |  | 
|  | static void BM_AssetManagerSetConfigurationFrameworkOld(benchmark::State& state) { | 
|  | AssetManager assets; | 
|  | if (!assets.addAssetPath(String8(kFrameworkPath), nullptr /*cookie*/, false /*appAsLib*/, | 
|  | true /*isSystemAssets*/)) { | 
|  | state.SkipWithError("Failed to load assets"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | const ResTable& table = assets.getResources(true); | 
|  |  | 
|  | ResTable_config config; | 
|  | memset(&config, 0, sizeof(config)); | 
|  |  | 
|  | while (state.KeepRunning()) { | 
|  | config.sdkVersion = ~config.sdkVersion; | 
|  | assets.setConfiguration(config); | 
|  | } | 
|  | } | 
|  | BENCHMARK(BM_AssetManagerSetConfigurationFrameworkOld); | 
|  |  | 
|  | }  // namespace android |