diff options
author | 2025-03-20 12:17:05 -0700 | |
---|---|---|
committer | 2025-03-20 22:38:25 -0700 | |
commit | 984a84eed846b5c04265057075d574b440564168 (patch) | |
tree | 347bc58ec194f0670dbf5f6612079fc8f4fa9b99 /libs | |
parent | c74a0961123efd89b350476e6d7a49b623e1d798 (diff) |
[res] A bit more efficient locale collection
Don't copy the string unless it's a new locale, and limit
the allocations as well
Test: unit tests
Flag: EXEMPT minor performance improvement
Change-Id: Icfe433ab211a0ca22882bd579415a96dc40db30a
Diffstat (limited to 'libs')
-rw-r--r-- | libs/androidfw/AssetManager2.cpp | 9 | ||||
-rw-r--r-- | libs/androidfw/LoadedArsc.cpp | 12 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/AssetManager2.h | 4 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/LoadedArsc.h | 3 | ||||
-rw-r--r-- | libs/androidfw/tests/AssetManager2_bench.cpp | 2 | ||||
-rw-r--r-- | libs/androidfw/tests/AssetManager2_test.cpp | 2 |
6 files changed, 18 insertions, 14 deletions
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index e09ab5fd1643..f169cfa68946 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -600,12 +600,12 @@ base::expected<std::set<ResTable_config>, IOError> AssetManager2::GetResourceCon return configurations; } -std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system, - bool merge_equivalent_languages) const { +LoadedPackage::Locales AssetManager2::GetResourceLocales( + bool exclude_system, bool merge_equivalent_languages) const { ATRACE_NAME("AssetManager::GetResourceLocales"); auto op = StartOperation(); - std::set<std::string> locales; + LoadedPackage::Locales locales; const auto non_system_overlays = exclude_system ? GetNonSystemOverlays() : std::set<ApkAssetsPtr>(); @@ -619,8 +619,7 @@ std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system, if (!non_system_overlays.empty()) { // Exclude overlays that target only system resources. const auto& apk_assets = GetApkAssets(package_group.cookies_[i]); - if (apk_assets && apk_assets->IsOverlay() && - non_system_overlays.find(apk_assets) == non_system_overlays.end()) { + if (apk_assets && apk_assets->IsOverlay() && !non_system_overlays.contains(apk_assets)) { continue; } } diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index d9166a16cdea..7cebb6d79502 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -361,14 +361,18 @@ base::expected<std::monostate, IOError> LoadedPackage::CollectConfigurations( return {}; } -void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const { - char temp_locale[RESTABLE_MAX_LOCALE_LEN]; +void LoadedPackage::CollectLocales(bool canonicalize, + Locales* out_locales) const { for (const auto& type_spec : type_specs_) { for (const auto& type_entry : type_spec.second.type_entries) { if (type_entry.config.locale != 0) { + char temp_locale[RESTABLE_MAX_LOCALE_LEN]; type_entry.config.getBcp47Locale(temp_locale, canonicalize); - std::string locale(temp_locale); - out_locales->insert(std::move(locale)); + auto locale_sv = std::string_view(temp_locale); + if (auto it = out_locales->lower_bound(locale_sv); + it == out_locales->end() || *it != locale_sv) { + out_locales->emplace_hint(it, locale_sv); + } } } } diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index b0179524f6cd..69fb3b39b5d2 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -189,8 +189,8 @@ class AssetManager2 { // ('android' package, other libraries) will be excluded from the list. // If `merge_equivalent_languages` is set to true, resource locales will be canonicalized // and de-duped in the resulting list. - std::set<std::string> GetResourceLocales(bool exclude_system = false, - bool merge_equivalent_languages = false) const; + LoadedPackage::Locales GetResourceLocales( + bool exclude_system = false, bool merge_equivalent_languages = false) const; // Searches the set of APKs loaded by this AssetManager and opens the first one found located // in the assets/ directory. diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h index 413b27829474..eb99dc7b8eff 100644 --- a/libs/androidfw/include/androidfw/LoadedArsc.h +++ b/libs/androidfw/include/androidfw/LoadedArsc.h @@ -238,7 +238,8 @@ class LoadedPackage { // Populates a set of strings representing locales. // If `canonicalize` is set to true, each locale is transformed into its canonical format // before being inserted into the set. This may cause some equivalent locales to de-dupe. - void CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const; + using Locales = std::set<std::string, std::less<>>; + void CollectLocales(bool canonicalize, Locales* out_locales) const; // type_idx is TT - 1 from 0xPPTTEEEE. inline const TypeSpec* GetTypeSpecByTypeIndex(uint8_t type_index) const { diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp index 136f5ea639a1..c469817d3595 100644 --- a/libs/androidfw/tests/AssetManager2_bench.cpp +++ b/libs/androidfw/tests/AssetManager2_bench.cpp @@ -191,7 +191,7 @@ static void BM_AssetManagerGetResourceLocales(benchmark::State& state) { assets.SetApkAssets({apk}); for (auto&& _ : state) { - std::set<std::string> locales = + auto locales = assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/); benchmark::DoNotOptimize(locales); } diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp index 3f228841f6ba..01da902674bb 100644 --- a/libs/androidfw/tests/AssetManager2_test.cpp +++ b/libs/androidfw/tests/AssetManager2_test.cpp @@ -621,7 +621,7 @@ TEST_F(AssetManager2Test, GetResourceLocales) { AssetManager2 assetmanager; assetmanager.SetApkAssets({system_assets_, basic_de_fr_assets_}); - std::set<std::string> locales = assetmanager.GetResourceLocales(); + auto locales = assetmanager.GetResourceLocales(); // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets. EXPECT_EQ(3u, locales.size()); |