writeString method

void writeString(
  1. String value
)

Write {@link String} string to the buffer

Research

Background / Overview

According to the following benchmark tests and real world scenarios, this method will choose different iterator based on the length of the string for more efficiency, called SSO(Short / Small String Optimization).

If string length small than {@link #SSO_SMALL_STRING_MAX_LENGTH}, will use {@link String#charAt(int)} to iterate, otherwise will use {@link String#getChars(int, int, char[], int)}

Benchmark

Test Cases

{@code
  int charAt(final String data) {
    final int len = data.length();
    for (int i = 0; i < len; i++) {
      if (data.charAt(i) <= ' ') {
        doThrow();
      }
    }
    return len;
  }

int getChars(final char[] reusable, final String data) { final int len = data.length(); data.getChars(0, len, reusable, 0); for (int i = 0; i < len; i++) { if (reusablei <= ' ') { doThrow(); } } return len; }

int toCharArray(final String data) { final int len = data.length(); final char[] copy = data.toCharArray(); for (int i = 0; i < len; i++) { if (copyi <= ' ') { doThrow(); } } return len; } }

Results

(run tests on HUAWEI JSN-AL00a with Android 9)
  ======= (tries per size: 1000) =======
  Size   charAt  getChars    toCharArray
     1   357.00  1,289.00    567.00
     2   179.00    202.00    300.00
     4    87.75     95.75    141.25
     8    46.63     46.88     73.75
    16    25.06     25.06     41.44
    32    14.53     14.13     24.22
    64     8.66      8.05     12.45
   128     6.23      5.22      8.27
   256     4.84      3.89      6.13
   512     4.10      3.21      5.44
  1024     3.91      4.36      4.83
  2048     3.67      2.78      4.85
  4096     4.01      2.65      6.32
  8192     3.60      2.63      6.42
 16384     3.65      2.61      5.39
 32768     3.61      2.60      4.91
 65536     3.57      2.62      4.68
 Rate in nanoseconds per character inspected

Obviously we can discover two facts, {@link String#toCharArray()} performance is lower than other methods at any time, and there is a dividing line when the string has 32({@link #SSO_SMALL_STRING_MAX_LENGTH}) characters.

@param value data @see Fastest way to iterate over all the chars in a String @see What is the easiest/best/most correct way to iterate through the characters of a string in Java?

Implementation

void writeString(String value) {
  int length = value.length;

  if (length > _kSSOSmallStringMaxLength) {
    _writeLongString(value);
  } else {
    _writeShortString(value);
  }
}