src/share/classes/java/lang/Integer.java

Print this page
rev 7120 : 8007398: Peformance improvements to Integer and Long string formatting.
Reviewed-by: mdugiou, martin, darcy
Contributed-by: Steven Schlansker <stevenschlansker@gmail.com>, Mike Duigou <mike.duigou@oracle.com>

@@ -24,11 +24,10 @@
  */
 
 package java.lang;
 
 import java.lang.annotation.Native;
-import java.util.Properties;
 
 /**
  * The {@code Integer} class wraps a value of the primitive type
  * {@code int} in an object. An object of type {@code Integer}
  * contains a single field whose type is {@code int}.

@@ -183,11 +182,11 @@
      * @return  an unsigned string representation of the argument in the specified radix.
      * @see     #toString(int, int)
      * @since 1.8
      */
     public static String toUnsignedString(int i, int radix) {
-        return Long.toString(toUnsignedLong(i), radix);
+        return Long.toUnsignedString(toUnsignedLong(i), radix);
     }
 
     /**
      * Returns a string representation of the integer argument as an
      * unsigned integer in base&nbsp;16.

@@ -305,24 +304,43 @@
     }
 
     /**
      * Convert the integer to an unsigned number.
      */
-    private static String toUnsignedString0(int i, int shift) {
-        char[] buf = new char[32];
-        int charPos = 32;
+    private static String toUnsignedString0(int val, int shift) {
+        // assert shift > 0 && shift <=5 : "Illegal shift value";
+        int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
+        int chars = Math.max(((mag + (shift - 1)) / shift), 1);
+        char[] buf = new char[chars];
+
+        formatUnsignedInt(val, shift, buf, 0, chars);
+
+        // Use special constructor which takes over "buf".
+        return new String(buf, true);
+    }
+
+    /**
+     * Format a long (treated as unsigned) into a character buffer.
+     * @param val the unsigned int to format
+     * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
+     * @param buf the character buffer to write to
+     * @param offset the offset in the destination buffer to start at
+     * @param len the number of characters to write
+     * @return the lowest character  location used
+     */
+     static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
+        int charPos = len;
         int radix = 1 << shift;
         int mask = radix - 1;
         do {
-            buf[--charPos] = digits[i & mask];
-            i >>>= shift;
-        } while (i != 0);
+            buf[offset + --charPos] = Integer.digits[val & mask];
+            val >>>= shift;
+        } while (val != 0 && charPos > 0);
 
-        return new String(buf, charPos, (32 - charPos));
+        return charPos;
     }
 
-
     final static char [] DigitTens = {
         '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
         '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
         '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
         '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',

@@ -873,10 +891,11 @@
 
     /**
      * Returns the value of this {@code Integer} as a {@code long}
      * after a widening primitive conversion.
      * @jls 5.1.2 Widening Primitive Conversions
+     * @see Integer#toUnsignedLong(int)
      */
     public long longValue() {
         return (long)value;
     }