Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ThemedResourceCache: Replace ArrayMap with HashMap for performance
When opening and closing activities in Settings, a significant amount of CPU time is spent looking up ArrayMap entries, as reported by simpleperf: 0.12% /system/framework/arm64/boot-framework.oat android.util.ArrayMap.binarySearchHashes ThemedResourceCache is responsible for a significant portion of the time spent in ArrayMap lookups: 0.08% 0.08% /system/framework/arm64/boot-framework.oat android.util.ArrayMap.binarySearchHashes | -- android.util.ArrayMap.binarySearchHashes | --50.00%-- android.util.ArrayMap.indexOf | |--36.71%-- android.util.ArrayMap.get | |--0.87%-- [hit in function] | | | |--9.64%-- android.content.res.ThemedResourceCache.getThemedLocked | | android.content.res.ThemedResourceCache.get | | | | | |--77.92%-- android.content.res.DrawableCache.getInstance | | | android.content.res.ResourcesImpl.loadDrawable | | | android.content.res.Resources.loadDrawable | | | android.content.res.TypedArray.getDrawableForDensity | | | android.content.res.Resources.getColor [DEDUPED] | | | | | | | |--62.94%-- android.view.View.<init> | | | | | | | | | |--64.58%-- android.view.ViewGroup.<init> | | | | | android.widget.LinearLayout.<init> | | | | | android.widget.LinearLayout.<init> | | | | | art_quick_invoke_stub | | | | | art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) | | | | | art::InvokeConstructor(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::ObjPtr<art::mirror::Object>, _jobject*) | | | | | art::Constructor_newInstance0(_JNIEnv*, _jobject*, _jobjectArray*) | | | | | art_jni_trampoline | | | | | java.lang.reflect.Constructor.newInstance | | | | | android.view.LayoutInflater.createView | | | | | com.android.internal.policy.PhoneLayoutInflater.onCreateView | | | | | android.view.LayoutInflater.onCreateView | | | | | android.view.LayoutInflater.onCreateView | | | | | android.view.LayoutInflater.createViewFromTag | | | | | android.view.LayoutInflater.inflate | | | | | android.view.LayoutInflater.inflate | | | | | | | | | --35.42%-- android.widget.TextView.<init> | | | | android.widget.Button.<init> | | | | art_quick_invoke_stub | | | | art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) | | | | art::InvokeConstructor(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::ObjPtr<art::mirror::Object>, _jobject*) | | | | art::Constructor_newInstance0(_JNIEnv*, _jobject*, _jobjectArray*) | | | | art_jni_trampoline | | | | java.lang.reflect.Constructor.newInstance | | | | android.view.LayoutInflater.createView | | | | com.android.internal.policy.PhoneLayoutInflater.onCreateView | | | | android.view.LayoutInflater.onCreateView | | | | android.view.LayoutInflater.onCreateView | | | | android.view.LayoutInflater.createViewFromTag | | | | android.view.LayoutInflater.rInflate | | | | android.view.LayoutInflater.rInflate | | | | android.view.LayoutInflater.rInflate | | | | android.view.LayoutInflater.inflate | | | | android.view.LayoutInflater.inflate | | | | android.view.LayoutInflater.inflate | | | | | | | --37.06%-- com.android.internal.widget.ToolbarWidgetWrapper.<init> | | | | | --22.08%-- android.content.res.ConfigurationBoundResourceCache.get | | android.content.res.ConfigurationBoundResourceCache.getInstance | | android.content.res.ResourcesImpl.loadComplexColorFromName | | android.content.res.ResourcesImpl.loadColorStateList | | android.content.res.Resources.loadColorStateList | | android.content.res.TypedArray.getColorStateList | | android.widget.TextView.readTextAppearance | | android.widget.TextView.setTextAppearance | | android.widget.TextView.setTextAppearance | | android.widget.Toolbar.setTitle | | com.android.wifi.x.com.android.internal.util.StateMachine$SmHandler.handleMessage | | android.view.SurfaceControl.copyFrom Empirical testing reveals that mThemedEntries usually contains around 14 entries, at which HashMap is 35% faster than ArrayMap for lookups and 54% faster [1] for insertions. The increased memory usage should be negligible at this size, so we can safely convert the map to a HashMap in order to improve performance in this hotpath. [1] https://docs.google.com/spreadsheets/d/136UJS2yVlZyPx30KDNgj4AWldkp9xbzIcWkLFj9RGgk/edit Test: simpleperf record -a; verify that ThemedResourceCache no longer appears under ArrayMap.binarySearchHashes Change-Id: I39e1c4b03fe0e60f933f02e253d2d3c4a483146f
- Loading branch information