• Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 7
    • 7
    • core-libs
    • b43
    • generic
    • generic
    • Not verified

      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.

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

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: