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

Commit 310e2e56 authored by Devin Moore's avatar Devin Moore Committed by Android (Google) Code Review
Browse files

Merge "Increase parcel capacity before writing strings in String16 array" into main

parents 9c99fa35 2b070546
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
@@ -233,4 +233,95 @@ public class ParcelPerfTest {
        }
    }

    private String[] createStringArray(int size, boolean inBmp) {
        String[] array = new String[size];
        for (int i = 0; i < size; i++) {
            if (inBmp) {
                array[i] = "a long string to be written";
            } else {
                // These are 4 bytes per char in UTF-16
                array[i] = "𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯𝒯";
            }
        }
        return array;
    }

    @Test
    public void timeWriteString16Array_1() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final String[] val = createStringArray(1, true);
        while (state.keepRunning()) {
            Parcel p = Parcel.obtain();
            p.writeString16Array(val);
            p.recycle();
        }
    }

    @Test
    public void timeWriteString16Array_100() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final String[] val = createStringArray(100, true);
        while (state.keepRunning()) {
            Parcel p = Parcel.obtain();
            p.writeString16Array(val);
            p.recycle();
        }
    }

    @Test
    public void timeWriteString16Array_1000() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final String[] val = createStringArray(1000, true);
        while (state.keepRunning()) {
            Parcel p = Parcel.obtain();
            p.writeString16Array(val);
            p.recycle();
        }
    }

    @Test
    public void timeWriteString16Array_1_notBmp() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final String[] val = createStringArray(1, false);
        while (state.keepRunning()) {
            Parcel p = Parcel.obtain();
            p.writeString16Array(val);
            p.recycle();
        }
    }

    @Test
    public void timeWriteString16Array_100_notBmp() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final String[] val = createStringArray(100, false);
        while (state.keepRunning()) {
            Parcel p = Parcel.obtain();
            p.writeString16Array(val);
            p.recycle();
        }
    }

    @Test
    public void timeWriteString16Array_1000_notBmp() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final String[] val = createStringArray(1000, false);
        while (state.keepRunning()) {
            Parcel p = Parcel.obtain();
            p.writeString16Array(val);
            p.recycle();
        }
    }

    @Test
    public void timeWriteString16ArrayOverhead_1000() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final String[] val = createStringArray(1000, true);
        while (state.keepRunning()) {
            int size = 0;
            for (int i = 0; i < val.length; i++) {
                size += (val[i].length() * 2 + 2 + 3) & ~3 + 4;
            }
        }
    }

}
+18 −0
Original line number Diff line number Diff line
@@ -2090,6 +2090,24 @@ public final class Parcel {
    public final void writeString16Array(@Nullable String[] val) {
        if (val != null) {
            int N = val.length;
            // reduce the number of times we need to growData from writing each String16
            int size = 4; // int32_t for the size of the array
            for (int i = 0; i < N; i++) {
                if (val[i] == null) {
                    size += 4; // we write a -1 for len for null strings
                } else {
                    // + 4 byte int32 for len
                    // String.length() * 2 because each char is at least one
                    // UTF-16 code point (2 bytes)
                    // + 2 for null char
                    // The string + null is padded for 4 byte alignment
                    size += ((val[i].length() * 2 + 2 + 3) & ~3) + 4;
                }
            }
            size += dataPosition();
            // size * 3/2 is what growData uses
            if (dataCapacity() < size) setDataCapacity(size / 2 * 3);

            writeInt(N);
            for (int i=0; i<N; i++) {
                writeString16(val[i]);