Merge "Double speed of Parcel.writeString()."

This commit is contained in:
TreeHugger Robot
2020-11-05 19:52:34 +00:00
committed by Android (Google) Code Review
2 changed files with 100 additions and 21 deletions

View File

@@ -0,0 +1,70 @@
/*
* 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 android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import androidx.test.filters.LargeTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
@LargeTest
@RunWith(Parameterized.class)
public class ParcelStringPerfTest {
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Parameterized.Parameter(0)
public String mName;
@Parameterized.Parameter(1)
public String mValue;
@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> getParameters() {
return Arrays.asList(new Object[][] {
{ "simple", "com.example.typical_package_name" },
{ "complex", "從不喜歡孤單一個 - 蘇永康/吳雨霏" },
});
}
@Test
public void timeWriteString8() {
final Parcel parcel = Parcel.obtain();
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
parcel.setDataPosition(0);
parcel.writeString8(mValue);
}
}
@Test
public void timeWriteString16() {
final Parcel parcel = Parcel.obtain();
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
parcel.setDataPosition(0);
parcel.writeString16(mValue);
}
}
}

View File

@@ -252,20 +252,25 @@ static void android_os_Parcel_nativeSignalExceptionForError(JNIEnv* env, jclass
signalExceptionForError(env, clazz, err); signalExceptionForError(env, clazz, err);
} }
static void android_os_Parcel_writeString8(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val) static void android_os_Parcel_writeString8(JNIEnv *env, jclass clazz, jlong nativePtr,
{ jstring val) {
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) { if (parcel != nullptr) {
status_t err = NO_MEMORY; status_t err = NO_ERROR;
if (val) { if (val) {
const size_t len = env->GetStringUTFLength(val); // NOTE: Keep this logic in sync with Parcel.cpp
const char* str = env->GetStringUTFChars(val, 0); const size_t len = env->GetStringLength(val);
if (str) { const size_t allocLen = env->GetStringUTFLength(val);
err = parcel->writeString8(str, len); err = parcel->writeInt32(allocLen);
env->ReleaseStringUTFChars(val, str); char *data = reinterpret_cast<char*>(parcel->writeInplace(allocLen + sizeof(char)));
if (data != nullptr) {
env->GetStringUTFRegion(val, 0, len, data);
*(data + allocLen) = 0;
} else {
err = NO_MEMORY;
} }
} else { } else {
err = parcel->writeString8(NULL, 0); err = parcel->writeString8(nullptr, 0);
} }
if (err != NO_ERROR) { if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err); signalExceptionForError(env, clazz, err);
@@ -273,21 +278,25 @@ static void android_os_Parcel_writeString8(JNIEnv* env, jclass clazz, jlong nati
} }
} }
static void android_os_Parcel_writeString16(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val) static void android_os_Parcel_writeString16(JNIEnv *env, jclass clazz, jlong nativePtr,
{ jstring val) {
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) { if (parcel != nullptr) {
status_t err = NO_MEMORY; status_t err = NO_ERROR;
if (val) { if (val) {
const jchar* str = env->GetStringCritical(val, 0); // NOTE: Keep this logic in sync with Parcel.cpp
if (str) { const size_t len = env->GetStringLength(val);
err = parcel->writeString16( const size_t allocLen = len * sizeof(char16_t);
reinterpret_cast<const char16_t*>(str), err = parcel->writeInt32(len);
env->GetStringLength(val)); char *data = reinterpret_cast<char*>(parcel->writeInplace(allocLen + sizeof(char16_t)));
env->ReleaseStringCritical(val, str); if (data != nullptr) {
env->GetStringRegion(val, 0, len, reinterpret_cast<jchar*>(data));
*reinterpret_cast<char16_t*>(data + allocLen) = 0;
} else {
err = NO_MEMORY;
} }
} else { } else {
err = parcel->writeString16(NULL, 0); err = parcel->writeString16(nullptr, 0);
} }
if (err != NO_ERROR) { if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err); signalExceptionForError(env, clazz, err);