Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44476e68 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Double speed of Parcel.writeString().

Previous logic was using GetStringUTFChars() and GetStringCritical(),
which resulted in making a new temporary heap allocation and an extra
memcpy().  The new approach in this CL bypasses those operations by
asking the JNI helpers to copy directly into the Parcel buffer.

This does mean that the contract for writing strings (prefixed with
length) is now duplicated in Parcel.cpp and android_os_Parcel.cpp,
so we leave docs to ensure future maintainers keep them in sync.

Benchmarking shows that this change improves performance by ~36%
for UTF-8 strings and ~52% for UTF-16 strings:

Before:
    timeWriteString8[simple]_mean: 1323
    timeWriteString8[complex]_mean: 2103
    timeWriteString16[simple]_mean: 1427
    timeWriteString16[complex]_mean: 1368

After:
    timeWriteString8[simple]_mean: 846
    timeWriteString8[complex]_mean: 1671
    timeWriteString16[simple]_mean: 685
    timeWriteString16[complex]_mean: 748

Bug: 172562452
Test: atest CorePerfTests:android.os.ParcelStringPerfTest
Exempt-From-Owner-Approval: trivial docs
Change-Id: I57754eac7af235a0a1bce9642d4923856bb04b78
parent a267bd37
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1068,6 +1068,7 @@ status_t Parcel::writeString8(const char* str, size_t len)
{
    if (str == nullptr) return writeInt32(-1);

    // NOTE: Keep this logic in sync with android_os_Parcel.cpp
    status_t err = writeInt32(len);
    if (err == NO_ERROR) {
        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char));
@@ -1108,6 +1109,7 @@ status_t Parcel::writeString16(const char16_t* str, size_t len)
{
    if (str == nullptr) return writeInt32(-1);

    // NOTE: Keep this logic in sync with android_os_Parcel.cpp
    status_t err = writeInt32(len);
    if (err == NO_ERROR) {
        len *= sizeof(char16_t);