Improving efficiency of StreamEncoder::append(CharSequence) and StreamEncoder::(CharSequence, int, int)

XMLWordPrintable

    • Type: Sub-task
    • Resolution: Unresolved
    • Priority: P4
    • 27
    • Affects Version/s: None
    • Component/s: core-libs
    • None
    • Fix Understood

      This sub task of JDK-8356679 proposes implementation-only changes to sun.nio.cs.StreamEncoder. No API is changed. Implementation behavior is slightly changed w.r.t to self-calls to non-private methods, which should not be a risk, as StreamEncoder is final.

      The target is to make the StreamEncoder::append(CharSequence) and StreamEncoder::append(CharSequence, int, int) methods *in the non-String* case be as efficient as they are already *in the String* case.

      This is achived by now handling CharSequence in *the exact same* optimized way as String was specifically handled before. This generalization of the previously String-specific optimization is possible since Java 25, thanks to the new CharSequence::getChars(int, int, char[], int) bulk-read method.

      Prior to the proposed change, the code was unefficient, as ontop of what the String-case did, the text content of other CharSequences (like StringBuilder and CharBuffer) had to be copied *once or multiply*, before it was finally processed *as* a String.

      The changes in detail are:
      * Extract the original implementation of StreamEncoder::write(String, int, int) to become a newly introduced, internal method StreamEncoder::implWrite(CharSequence, int, int). This allows making use of that exact original implementation by other methods, particularly StreamEncoder::append.
      * StringEncoder::append(CharSequence) prevents the previously implied creation of an intermediate String representation in the non-String case (which implied creating another temporary object on the heap, and duplicating full text content), ontop of what the String case did.
      * StringEncoder::append(CharSequence, int, int), in addition to the optimization of the single-arg case, also prevents the previously implied creation of a sub sequence for non-CharBuffer cases (which always meant to create another temporary object on the heap, and in many cases meant to duplicate partial text content). The CharBuffer-case exemption is preserved to still make use of its existing fast-path, as CharBuffers do not create temporary copies on subsequence(int, int) calls.
      * As a side optimization, StringEncoder::write and StringEncode::apend prevent the creation of temporary ZERO-size buffers, effectively turning these methods into more or less no-ops.

            Assignee:
            Markus Karg
            Reporter:
            Markus Karg
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: