Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6642323

Speeding up Single Byte Decoders

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 7
    • Fix Version/s: 7
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b43
    • CPU:
      generic
    • OS:
      generic
    • Verification:
      Not verified

      Description

      Here's the critical decoder loop for ASCII

      private CoderResult decodeArrayLoop(ByteBuffer src,
      CharBuffer dst)
      {
      byte[] sa = src.array();
      int sp = src.arrayOffset() + src.position();
      int sl = src.arrayOffset() + src.limit();
      assert (sp <= sl);
      sp = (sp <= sl ? sp : sl);
      char[] da = dst.array();
      int dp = dst.arrayOffset() + dst.position();
      int dl = dst.arrayOffset() + dst.limit();
      assert (dp <= dl);
      dp = (dp <= dl ? dp : dl);

      try {
      while (sp < sl) {
      byte b = sa[sp];
      if (b >= 0) {
      if (dp >= dl)
      return CoderResult.OVERFLOW;
      da[dp++] = (char)b;
      sp++;
      continue;
      }
      return CoderResult.malformedForLength(1);
      }
      return CoderResult.UNDERFLOW;
      } finally {
      src.position(sp - src.arrayOffset());
      dst.position(dp - dst.arrayOffset());
      }
      }


      We can optimize the inner loop by checking for overflow and underflow at the same time.


              private static CoderResult normalResult(ByteBuffer src, int sp,
                                                      CharBuffer dst, int dp) {
                  updateBufferPositions(src, sp, dst, dp);
                  return src.hasRemaining() ?
                      CoderResult.OVERFLOW :
                      CoderResult.UNDERFLOW;
              }

      private CoderResult decodeArrayLoop(ByteBuffer src,
      CharBuffer dst)
      {
      byte[] sa = src.array();
      int sp = src.arrayOffset() + src.position();
      int sl = src.arrayOffset() + src.limit();

                  char[] da = dst.array();
      int dp = dst.arrayOffset() + dst.position();
                  int dl = dp + Math.min(src.remaining(),
                                         dst.remaining());
                  while (dp < dl) {
                      byte b = sa[sp];
                      if (b >= 0) {
                          da[dp++] = (char)b;
                          sp++;
                      } else
                          return coderResult(CoderResult.malformedForLength(1),
                                             src, sp, dst, dp);
                  }
                  return normalResult(src, sp, dst, dp);
              }
       

      Similarly, for ISO-8859-1, we can optimize thus:

                  int dl = dp + Math.min(src.remaining(),
                                         dst.remaining());
                  while (dp < dl) {
                      da[dp++] = (char)(sa[sp++] & 0xff);
                  }
                  return normalResult(src, sp, dst, dp);

      For other table-driven single byte decoders,
      we can index into a char array instead of adding
      a degree of indirection by indexing into a String.
      If all bytes are valid, we can eliminate a check for unmappable
      characters. For e.g. ISO-8859-15, we are left with the tight inner loop

                   while (dp < dl) {
                      da[dp++] = byteToChar[sa[sp++] & 0xff];
                  }

      Simple benchmarking shows approximately a factor of two speedup
      of decoding of long random byte sequences.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                sherman Xueming Shen
                Reporter:
                martin Martin Buchholz
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: