From b293d933e0297dc9a5b8b0c7f8ca939bd8f53267 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 23 Feb 2021 21:29:18 +0800 Subject: [PATCH] Optimize the Parcel read/write of common window data The Parcel read/write speed of MergedConfiguration/InsetsSource becomes 4x+ faster. Because writeParcelable sends additional type info which is unnecessary if the type is known on the reading side, replace the usages to writeTypedObject and well-written readFromParcel. That saves the time of class lookup and object creation. Bug: 181025587 Test: vogar --mode app_process --benchmark \ frameworks/base/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java Change-Id: I29548ce6c2e5886f0e90a5dc70d8e9ecc0fb25a8 --- .../java/android/app/WindowConfiguration.java | 25 ++-- .../android/content/res/Configuration.java | 8 +- .../android/util/MergedConfiguration.java | 18 +-- core/java/android/view/InsetsSource.java | 13 +- .../android/view/InsetsSourceControl.java | 8 +- core/java/android/view/InsetsState.java | 10 +- .../android/window/ClientWindowFrames.java | 6 +- .../src/android/os/ParcelableBenchmark.java | 133 ++++++++++++++++++ 8 files changed, 171 insertions(+), 50 deletions(-) create mode 100644 core/tests/benchmarks/src/android/os/ParcelableBenchmark.java diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java index 4ae1670e90412..d04ca1d9a48e7 100644 --- a/core/java/android/app/WindowConfiguration.java +++ b/core/java/android/app/WindowConfiguration.java @@ -57,7 +57,7 @@ public class WindowConfiguration implements Parcelable, Comparable + *
  • Well-written read/writeFromParcel (direct access)
  • + *
  • read/writeTypedObject (object creation + addition int to indicate nullity)
  • + *
  • read/writeParcelable (object creation + addition type String)
  • + * + */ +public class ParcelableBenchmark { + private Parcel mParcel; + + @BeforeExperiment + protected void setUp() { + mParcel = Parcel.obtain(); + } + + @AfterExperiment + protected void tearDown() { + mParcel.recycle(); + mParcel = null; + } + + public void timeReadWriteMergedConfiguration(int reps) { + final MergedConfiguration mergedConfiguration = new MergedConfiguration(); + for (int i = 0; i < reps; i++) { + mergedConfiguration.writeToParcel(mParcel, 0); + mParcel.setDataPosition(0); + mergedConfiguration.readFromParcel(mParcel); + } + } + + public void timeReadWriteInsetsState(int reps) { + final InsetsState insetsState = new InsetsState(); + for (int i = 0; i < InsetsState.SIZE; i++) { + insetsState.addSource(new InsetsSource(i)); + } + for (int i = 0; i < reps; i++) { + insetsState.writeToParcel(mParcel, 0); + mParcel.setDataPosition(0); + insetsState.readFromParcel(mParcel); + } + } + + public void timeReadWritePointArray(int reps) { + final PointArray pointArray = new PointArray(); + for (int i = 0; i < reps; i++) { + pointArray.writeToParcel(mParcel, 0); + mParcel.setDataPosition(0); + pointArray.readFromParcel(mParcel); + } + } + + public void timeReadWritePointArrayFast(int reps) { + final PointArrayFast pointArray = new PointArrayFast(); + for (int i = 0; i < reps; i++) { + pointArray.writeToParcel(mParcel, 0); + mParcel.setDataPosition(0); + pointArray.readFromParcel(mParcel); + } + } + + @SuppressLint("ParcelCreator") + private static class PointArray implements Parcelable { + Rect mBounds = new Rect(); + Point[] mPoints = new Point[10]; + { + for (int i = 0; i < mPoints.length; i++) { + mPoints[i] = new Point(); + } + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mBounds, flags); + dest.writeParcelableArray(mPoints, flags); + } + + void readFromParcel(Parcel in) { + mBounds = in.readParcelable(Rect.class.getClassLoader()); + mPoints = in.readParcelableArray(Point.class.getClassLoader(), Point.class); + } + + @Override + public int describeContents() { + return 0; + } + } + + @SuppressLint("ParcelCreator") + private static class PointArrayFast extends PointArray { + + @Override + public void writeToParcel(Parcel dest, int flags) { + mBounds.writeToParcel(dest, flags); + dest.writeTypedArray(mPoints, flags); + } + + @Override + void readFromParcel(Parcel in) { + mBounds.readFromParcel(in); + in.readTypedArray(mPoints, Point.CREATOR); + } + } +}