/* * 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()) { const ResolvedBag* bag = assets.GetBag(app::R::style::StyleTwo); 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