diff options
author | Jeff Sharkey <jsharkey@android.com> | 2020-04-20 21:26:27 -0600 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2020-04-21 09:38:36 -0600 |
commit | d387e79ae1cbc6b4fd16bfc315ec2fc63f6f6aca (patch) | |
tree | 275fd58ba3c81cd859400e907b793c8f534c172e /core/tests/benchmarks | |
parent | 6d18727690e430d60b17a4652966b018c5931c14 (diff) |
Offer to write Strings through Parcels as UTF-8.
Recently while investigating some Binder limits, I discovered that
we're still sending Strings across Binder as UTF-16, which is very
wasteful for two reasons:
1. The majority of data flowing through APIs like PackageManager is
already limited to US-ASCII, and by sending UTF-16 we're wasting
half of our transactions on null-byte overhead.
2. Internally ART is already "compressing" simple strings by storing
them as US-ASCII instead of UTF-16, meaning every time we want to
write a simple string to Binder, we're forced to first inflate it
to UTF-16.
This change first updates Parcel.cpp to accept char* UTF-8 strings,
similar to how it accepts char16_t* for UTF-16. It then offers
both UTF-8 and UTF-16 variants to Parcel.java via JNI. We also
update the String8 handling to behave identical to String16.
This change adds benchmarking to show that these new methods are
about 50% faster for US-ASCII strings, and about 68% faster for
complex strings that reference higher Unicode planes. (So an
improvement in both cases!)
Bug: 154436100
Test: atest FrameworksCoreTests:ParcelTest
Test: make core-libart conscrypt okhttp bouncycastle vogar caliper && vogar --mode app_process --benchmark frameworks/base/core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java
Change-Id: I22a11d3497486d922ec8e14c85df66ca096b8f2a
Diffstat (limited to 'core/tests/benchmarks')
-rw-r--r-- | core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java new file mode 100644 index 000000000000..daa90c28e0c4 --- /dev/null +++ b/core/tests/benchmarks/src/android/os/ParcelStringBenchmark.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 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. + */ + +package android.os; + +import com.google.caliper.AfterExperiment; +import com.google.caliper.BeforeExperiment; +import com.google.caliper.Param; + +public class ParcelStringBenchmark { + + @Param({"com.example.typical_package_name", "從不喜歡孤單一個 - 蘇永康/吳雨霏"}) + String mValue; + + private Parcel mParcel; + + @BeforeExperiment + protected void setUp() { + mParcel = Parcel.obtain(); + } + + @AfterExperiment + protected void tearDown() { + mParcel.recycle(); + mParcel = null; + } + + public void timeWriteString8(int reps) { + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.writeString8(mValue); + } + } + + public void timeReadString8(int reps) { + mParcel.writeString8(mValue); + + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.readString8(); + } + } + + public void timeWriteString16(int reps) { + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.writeString16(mValue); + } + } + + public void timeReadString16(int reps) { + mParcel.writeString16(mValue); + + for (int i = 0; i < reps; i++) { + mParcel.setDataPosition(0); + mParcel.readString16(); + } + } +} |