diff options
author | Ian Rogers <ian.rogers@manchester.ac.uk> | 2008-04-18 21:00:04 +0000 |
---|---|---|
committer | Ian Rogers <ian.rogers@manchester.ac.uk> | 2008-04-18 21:00:04 +0000 |
commit | 6d8bae6ff8dbdaea999ac2598904071492d5dd3e (patch) | |
tree | 04edbb802ed3e9ae3ad4cf114392a2d6f12f1e31 /java | |
parent | 109d4fd0bae4ec83346f1aeaf7d6480f5268471f (diff) | |
download | classpath-6d8bae6ff8dbdaea999ac2598904071492d5dd3e.tar.gz |
2008-04-18 Ian Rogers <ian.rogers@manchester.ac.uk>
* java/lang/Byte.java (static): initialize byteCache.
(valueOf(String,int)): use valueOf(byte) rather than new.
(valueOf(String)): likewise.
(valueOf(byte)): Switch from lazy initialization of cached values to
initialization at class initialization time. This removes the need for
synchronization in the common case.
(decode): use valueOf(byte) rather than new.
* java/lang/Character.java (static): initialize charCache.
(valueOf): Switch from lazy initialization of cached values to
initialization at class initialization time. This removes the need for
synchronization in the common case.
* java/lang/Double.java (ZERO): new private field.
(ONE): likewise.
(valueOf(double)): don't create new doubles for the case of 0 and 1.
(valueOf(String)): use valueOf(double) rather than new.
(equals): use raw bits for comparison to avoid division.
* java/lang/Float.java (ZERO): new private field.
(ONE): likewise.
(valueOf(float)): don't create new floats for the case of 0 and 1.
(valueOf(String)): use valueOf(float) rather than new.
(equals): use raw bits for comparison to avoid division.
* java/lang/Integer.java (static): initialize intCache.
(stringSize): new private method to estimate size of string for an int.
(toString): reuse digits for single character strings, for multiple
character strings estimate their length using string size method.
(valueOf(String,int)): use valueOf(int) rather than new.
(valueOf(String)): likewise.
(valueOf(int)): Switch from lazy initialization of cached values to
initialization at class initialization time. This removes the need for
synchronization in the common case.
(getInteger): use valueOf(int) rather than new.
(decode): use valueOf(int) rather than new.
(signum): use shift and subtract to compute value.
(toUnsignedString): calculate string size rather than using 32 chars.
* java/lang/Long.java (longCache): new private field.
(stringSize): new private method to estimate size of string for a long.
(toString): reuse digits for single character strings, for multiple
character strings estimate their length using string size method.
(valueOf(String,int)): use valueOf(long) rather than new.
(valueOf(String)): likewise.
(valueOf(long)): use cache of values.
(decode): use valueOf(long) rather than new.
(signum): use shift and subtract to compute value.
(toUnsignedString): calculate string size rather than using 64 chars.
* java/lang/Short.java (static): initialize shortCache.
(valueOf(String,int)): use valueOf(short) rather than new.
(valueOf(String)): likewise.
(valueOf(short)): Switch from lazy initialization of cached values to
initialization at class initialization time. This removes the need for
synchronization in the common case.
(decode): use valueOf(short) rather than new.
Diffstat (limited to 'java')
-rw-r--r-- | java/lang/Byte.java | 18 | ||||
-rw-r--r-- | java/lang/Character.java | 13 | ||||
-rw-r--r-- | java/lang/Double.java | 38 | ||||
-rw-r--r-- | java/lang/Float.java | 38 | ||||
-rw-r--r-- | java/lang/Integer.java | 119 | ||||
-rw-r--r-- | java/lang/Long.java | 139 | ||||
-rw-r--r-- | java/lang/Short.java | 19 |
7 files changed, 275 insertions, 109 deletions
diff --git a/java/lang/Byte.java b/java/lang/Byte.java index 7f53a494b..35d5402c2 100644 --- a/java/lang/Byte.java +++ b/java/lang/Byte.java @@ -88,6 +88,11 @@ public final class Byte extends Number implements Comparable<Byte> // This caches Byte values, and is used by boxing conversions via // valueOf(). We're required to cache all possible values here. private static Byte[] byteCache = new Byte[MAX_VALUE - MIN_VALUE + 1]; + static + { + for (byte i=MIN_VALUE; i <= MAX_VALUE; i++) + byteCache[i - MIN_VALUE] = new Byte(i); + } /** @@ -185,7 +190,7 @@ public final class Byte extends Number implements Comparable<Byte> */ public static Byte valueOf(String s, int radix) { - return new Byte(parseByte(s, radix)); + return valueOf(parseByte(s, radix)); } /** @@ -201,7 +206,7 @@ public final class Byte extends Number implements Comparable<Byte> */ public static Byte valueOf(String s) { - return new Byte(parseByte(s, 10)); + return valueOf(parseByte(s, 10)); } /** @@ -214,12 +219,7 @@ public final class Byte extends Number implements Comparable<Byte> */ public static Byte valueOf(byte val) { - synchronized (byteCache) - { - if (byteCache[val - MIN_VALUE] == null) - byteCache[val - MIN_VALUE] = new Byte(val); - return byteCache[val - MIN_VALUE]; - } + return byteCache[val - MIN_VALUE]; } /** @@ -258,7 +258,7 @@ public final class Byte extends Number implements Comparable<Byte> int i = Integer.parseInt(s, 10, true); if ((byte) i != i) throw new NumberFormatException(); - return new Byte((byte) i); + return valueOf((byte) i); } /** diff --git a/java/lang/Character.java b/java/lang/Character.java index 506033f31..eaa9557f6 100644 --- a/java/lang/Character.java +++ b/java/lang/Character.java @@ -2055,6 +2055,11 @@ public final class Character implements Serializable, Comparable<Character> // this constant controls how much we actually cache. private static final int MAX_CACHE = 127; private static Character[] charCache = new Character[MAX_CACHE + 1]; + static + { + for (char i=0; i <= MAX_CACHE; i++) + charCache[i] = new Character(i); + } /** * Lu = Letter, Uppercase (Informative). @@ -4208,12 +4213,8 @@ public final class Character implements Serializable, Comparable<Character> { if (val > MAX_CACHE) return new Character(val); - synchronized (charCache) - { - if (charCache[val - MIN_VALUE] == null) - charCache[val - MIN_VALUE] = new Character(val); - return charCache[val - MIN_VALUE]; - } + else + return charCache[val - MIN_VALUE]; } /** diff --git a/java/lang/Double.java b/java/lang/Double.java index a05514368..f3f7cb1e0 100644 --- a/java/lang/Double.java +++ b/java/lang/Double.java @@ -104,6 +104,16 @@ public final class Double extends Number implements Comparable<Double> public static final Class<Double> TYPE = (Class<Double>) VMClassLoader.getPrimitiveClass('D'); /** + * Cache representation of 0 + */ + private static final Double ZERO = new Double(0.0d); + + /** + * Cache representation of 1 + */ + private static final Double ONE = new Double(1.0d); + + /** * The immutable value of this Double. * * @serial the wrapped double @@ -261,8 +271,12 @@ public final class Double extends Number implements Comparable<Double> */ public static Double valueOf(double val) { - // We don't actually cache, but we could. - return new Double(val); + if ((val == 0.0) && (doubleToRawLongBits(val) == 0L)) + return ZERO; + else if (val == 1.0) + return ONE; + else + return new Double(val); } /** @@ -277,7 +291,7 @@ public final class Double extends Number implements Comparable<Double> */ public static Double valueOf(String s) { - return new Double(parseDouble(s)); + return valueOf(parseDouble(s)); } /** @@ -490,17 +504,13 @@ public final class Double extends Number implements Comparable<Double> */ public boolean equals(Object obj) { - if (! (obj instanceof Double)) - return false; - - double d = ((Double) obj).value; - - // Avoid call to native method. However, some implementations, like gcj, - // are better off using floatToIntBits(value) == floatToIntBits(f). - // Check common case first, then check NaN and 0. - if (value == d) - return (value != 0) || (1 / value == 1 / d); - return isNaN(value) && isNaN(d); + if (obj instanceof Double) + { + double d = ((Double) obj).value; + return (doubleToRawLongBits(value) == doubleToRawLongBits(d)) || + (isNaN(value) && isNaN(d)); + } + return false; } /** diff --git a/java/lang/Float.java b/java/lang/Float.java index 9060d026f..63e43c257 100644 --- a/java/lang/Float.java +++ b/java/lang/Float.java @@ -104,6 +104,16 @@ public final class Float extends Number implements Comparable<Float> public static final int SIZE = 32; /** + * Cache representation of 0 + */ + private static final Float ZERO = new Float(0.0f); + + /** + * Cache representation of 1 + */ + private static final Float ONE = new Float(1.0f); + + /** * The immutable value of this Float. * * @serial the wrapped float @@ -275,7 +285,7 @@ public final class Float extends Number implements Comparable<Float> */ public static Float valueOf(String s) { - return new Float(parseFloat(s)); + return valueOf(parseFloat(s)); } /** @@ -289,8 +299,12 @@ public final class Float extends Number implements Comparable<Float> */ public static Float valueOf(float val) { - // We don't actually cache, but we could. - return new Float(val); + if ((val == 0.0) && (floatToRawIntBits(val) == 0)) + return ZERO; + else if (val == 1.0) + return ONE; + else + return new Float(val); } /** @@ -500,17 +514,13 @@ public final class Float extends Number implements Comparable<Float> */ public boolean equals(Object obj) { - if (! (obj instanceof Float)) - return false; - - float f = ((Float) obj).value; - - // Avoid call to native method. However, some implementations, like gcj, - // are better off using floatToIntBits(value) == floatToIntBits(f). - // Check common case first, then check NaN and 0. - if (value == f) - return (value != 0) || (1 / value == 1 / f); - return isNaN(value) && isNaN(f); + if (obj instanceof Float) + { + float f = ((Float) obj).value; + return (floatToRawIntBits(value) == floatToRawIntBits(f)) || + (isNaN(value) && isNaN(f)); + } + return false; } /** diff --git a/java/lang/Integer.java b/java/lang/Integer.java index 62907ff77..8f32869a3 100644 --- a/java/lang/Integer.java +++ b/java/lang/Integer.java @@ -52,6 +52,7 @@ package java.lang; * @author Eric Blake (ebb9@email.byu.edu) * @author Tom Tromey (tromey@redhat.com) * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @author Ian Rogers * @since 1.0 * @status updated to 1.5 */ @@ -92,7 +93,12 @@ public final class Integer extends Number implements Comparable<Integer> // these constants control how much we actually cache. private static final int MIN_CACHE = -128; private static final int MAX_CACHE = 127; - private static Integer[] intCache = new Integer[MAX_CACHE - MIN_CACHE + 1]; + private static final Integer[] intCache = new Integer[MAX_CACHE - MIN_CACHE + 1]; + static + { + for (int i=MIN_CACHE; i <= MAX_CACHE; i++) + intCache[i - MIN_CACHE] = new Integer(i); + } /** * The immutable value of this Integer. @@ -126,6 +132,45 @@ public final class Integer extends Number implements Comparable<Integer> } /** + * Return the size of a string large enough to hold the given number + * + * @param num the number we want the string length for (must be positive) + * @param radix the radix (base) that will be used for the string + * @return a size sufficient for a string of num + */ + private static int stringSize(int num, int radix) { + int exp; + if (radix < 4) + { + exp = 1; + } + else if (radix < 8) + { + exp = 2; + } + else if (radix < 16) + { + exp = 3; + } + else if (radix < 32) + { + exp = 4; + } + else + { + exp = 5; + } + int size=0; + do + { + num >>>= exp; + size++; + } + while(num != 0); + return size; + } + + /** * Converts the <code>int</code> to a <code>String</code> using * the specified radix (base). If the radix exceeds * <code>Character.MIN_RADIX</code> or <code>Character.MAX_RADIX</code>, 10 @@ -142,22 +187,40 @@ public final class Integer extends Number implements Comparable<Integer> if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; - // For negative numbers, print out the absolute value w/ a leading '-'. - // Use an array large enough for a binary number. - char[] buffer = new char[33]; - int i = 33; - boolean isNeg = false; - if (num < 0) + // Is the value negative? + boolean isNeg = num < 0; + + // Is the string a single character? + if (!isNeg && num < radix) + return new String(digits, num, 1, true); + + // Compute string size and allocate buffer + // account for a leading '-' if the value is negative + int size; + int i; + char[] buffer; + if (isNeg) { - isNeg = true; num = -num; // When the value is MIN_VALUE, it overflows when made positive if (num < 0) { + i = size = stringSize(MAX_VALUE, radix) + 2; + buffer = new char[size]; buffer[--i] = digits[(int) (-(num + radix) % radix)]; num = -(num / radix); } + else + { + i = size = stringSize(num, radix) + 1; + buffer = new char[size]; + } + } + else + { + i = size = stringSize(num, radix); + buffer = new char[size]; } do @@ -171,7 +234,7 @@ public final class Integer extends Number implements Comparable<Integer> buffer[--i] = '-'; // Package constructor avoids an array copy. - return new String(buffer, i, 33 - i, true); + return new String(buffer, i, size - i, true); } /** @@ -275,7 +338,7 @@ public final class Integer extends Number implements Comparable<Integer> */ public static Integer valueOf(String s, int radix) { - return new Integer(parseInt(s, radix, false)); + return valueOf(parseInt(s, radix, false)); } /** @@ -291,7 +354,7 @@ public final class Integer extends Number implements Comparable<Integer> */ public static Integer valueOf(String s) { - return new Integer(parseInt(s, 10, false)); + return valueOf(parseInt(s, 10, false)); } /** @@ -306,12 +369,8 @@ public final class Integer extends Number implements Comparable<Integer> { if (val < MIN_CACHE || val > MAX_CACHE) return new Integer(val); - synchronized (intCache) - { - if (intCache[val - MIN_CACHE] == null) - intCache[val - MIN_CACHE] = new Integer(val); - return intCache[val - MIN_CACHE]; - } + else + return intCache[val - MIN_CACHE]; } /** @@ -440,7 +499,7 @@ public final class Integer extends Number implements Comparable<Integer> public static Integer getInteger(String nm, int val) { Integer result = getInteger(nm, null); - return result == null ? new Integer(val) : result; + return result == null ? valueOf(val) : result; } /** @@ -506,7 +565,7 @@ public final class Integer extends Number implements Comparable<Integer> */ public static Integer decode(String str) { - return new Integer(parseInt(str, 10, true)); + return valueOf(parseInt(str, 10, true)); } /** @@ -628,7 +687,7 @@ public final class Integer extends Number implements Comparable<Integer> */ public static int signum(int x) { - return x < 0 ? -1 : (x > 0 ? 1 : 0); + return (x >> 31) - (-x >> 31); } /** @@ -666,10 +725,22 @@ public final class Integer extends Number implements Comparable<Integer> // Package visible for use by Long. static String toUnsignedString(int num, int exp) { - // Use an array large enough for a binary number. + // Compute string length + int size = 1; + int copy = num >>> exp; + while (copy != 0) + { + size++; + copy >>>= exp; + } + // Quick path for single character strings + if (size == 1) + return new String(digits, num, 1, true); + + // Encode into buffer int mask = (1 << exp) - 1; - char[] buffer = new char[32]; - int i = 32; + char[] buffer = new char[size]; + int i = size; do { buffer[--i] = digits[num & mask]; @@ -678,7 +749,7 @@ public final class Integer extends Number implements Comparable<Integer> while (num != 0); // Package constructor avoids an array copy. - return new String(buffer, i, 32 - i, true); + return new String(buffer, i, size - i, true); } /** diff --git a/java/lang/Long.java b/java/lang/Long.java index 08ac3976c..d92676bb3 100644 --- a/java/lang/Long.java +++ b/java/lang/Long.java @@ -51,6 +51,7 @@ package java.lang; * @author Eric Blake (ebb9@email.byu.edu) * @author Tom Tromey (tromey@redhat.com) * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @author Ian Rogers * @since 1.0 * @status updated to 1.5 */ @@ -86,6 +87,18 @@ public final class Long extends Number implements Comparable<Long> */ public static final int SIZE = 64; + // This caches some Long values, and is used by boxing + // conversions via valueOf(). We cache at least -128..127; + // these constants control how much we actually cache. + private static final int MIN_CACHE = -128; + private static final int MAX_CACHE = 127; + private static final Long[] longCache = new Long[MAX_CACHE - MIN_CACHE + 1]; + static + { + for (int i=MIN_CACHE; i <= MAX_CACHE; i++) + longCache[i - MIN_CACHE] = new Long(i); + } + /** * The immutable value of this Long. * @@ -118,6 +131,45 @@ public final class Long extends Number implements Comparable<Long> } /** + * Return the size of a string large enough to hold the given number + * + * @param num the number we want the string length for (must be positive) + * @param radix the radix (base) that will be used for the string + * @return a size sufficient for a string of num + */ + private static int stringSize(long num, int radix) { + int exp; + if (radix < 4) + { + exp = 1; + } + else if (radix < 8) + { + exp = 2; + } + else if (radix < 16) + { + exp = 3; + } + else if (radix < 32) + { + exp = 4; + } + else + { + exp = 5; + } + int size=0; + do + { + num >>>= exp; + size++; + } + while(num != 0); + return size; + } + + /** * Converts the <code>long</code> to a <code>String</code> using * the specified radix (base). If the radix exceeds * <code>Character.MIN_RADIX</code> or <code>Character.MAX_RADIX</code>, 10 @@ -131,29 +183,43 @@ public final class Long extends Number implements Comparable<Long> */ public static String toString(long num, int radix) { - // Use the Integer toString for efficiency if possible. - if ((int) num == num) - return Integer.toString((int) num, radix); - if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; - // For negative numbers, print out the absolute value w/ a leading '-'. - // Use an array large enough for a binary number. - char[] buffer = new char[65]; - int i = 65; - boolean isNeg = false; - if (num < 0) + // Is the value negative? + boolean isNeg = num < 0; + + // Is the string a single character? + if (!isNeg && num < radix) + return new String(digits, (int)num, 1, true); + + // Compute string size and allocate buffer + // account for a leading '-' if the value is negative + int size; + int i; + char[] buffer; + if (isNeg) { - isNeg = true; num = -num; // When the value is MIN_VALUE, it overflows when made positive if (num < 0) - { - buffer[--i] = digits[(int) (-(num + radix) % radix)]; - num = -(num / radix); - } + { + i = size = stringSize(MAX_VALUE, radix) + 2; + buffer = new char[size]; + buffer[--i] = digits[(int) (-(num + radix) % radix)]; + num = -(num / radix); + } + else + { + i = size = stringSize(num, radix) + 1; + buffer = new char[size]; + } + } + else + { + i = size = stringSize(num, radix); + buffer = new char[size]; } do @@ -167,7 +233,7 @@ public final class Long extends Number implements Comparable<Long> buffer[--i] = '-'; // Package constructor avoids an array copy. - return new String(buffer, i, 65 - i, true); + return new String(buffer, i, size - i, true); } /** @@ -270,7 +336,7 @@ public final class Long extends Number implements Comparable<Long> */ public static Long valueOf(String s, int radix) { - return new Long(parseLong(s, radix, false)); + return valueOf(parseLong(s, radix, false)); } /** @@ -286,7 +352,7 @@ public final class Long extends Number implements Comparable<Long> */ public static Long valueOf(String s) { - return new Long(parseLong(s, 10, false)); + return valueOf(parseLong(s, 10, false)); } /** @@ -298,9 +364,10 @@ public final class Long extends Number implements Comparable<Long> */ public static Long valueOf(long val) { - // We aren't required to cache here. We could, though perhaps we - // ought to consider that as an empirical question. - return new Long(val); + if (val < MIN_CACHE || val > MAX_CACHE) + return new Long(val); + else + return longCache[((int)val) - MIN_CACHE]; } /** @@ -337,7 +404,7 @@ public final class Long extends Number implements Comparable<Long> */ public static Long decode(String str) { - return new Long(parseLong(str, 10, true)); + return valueOf(parseLong(str, 10, true)); } /** @@ -467,7 +534,7 @@ public final class Long extends Number implements Comparable<Long> public static Long getLong(String nm, long val) { Long result = getLong(nm, null); - return result == null ? new Long(val) : result; + return result == null ? valueOf(val) : result; } /** @@ -622,7 +689,7 @@ public final class Long extends Number implements Comparable<Long> */ public static int signum(long x) { - return x < 0 ? -1 : (x > 0 ? 1 : 0); + return (int)(x >> 63) - (int)(-x >> 63); } /** @@ -655,16 +722,22 @@ public final class Long extends Number implements Comparable<Long> */ private static String toUnsignedString(long num, int exp) { - // Use the Integer toUnsignedString for efficiency if possible. - // If NUM<0 then this particular optimization doesn't work - // properly. - if (num >= 0 && (int) num == num) - return Integer.toUnsignedString((int) num, exp); + // Compute string length + int size = 1; + long copy = num >>> exp; + while (copy != 0) + { + size++; + copy >>>= exp; + } + // Quick path for single character strings + if (size == 1) + return new String(digits, (int)num, 1, true); - // Use an array large enough for a binary number. + // Encode into buffer int mask = (1 << exp) - 1; - char[] buffer = new char[64]; - int i = 64; + char[] buffer = new char[size]; + int i = size; do { buffer[--i] = digits[(int) num & mask]; @@ -673,7 +746,7 @@ public final class Long extends Number implements Comparable<Long> while (num != 0); // Package constructor avoids an array copy. - return new String(buffer, i, 64 - i, true); + return new String(buffer, i, size - i, true); } /** diff --git a/java/lang/Short.java b/java/lang/Short.java index 41a31e260..ec87f933e 100644 --- a/java/lang/Short.java +++ b/java/lang/Short.java @@ -90,6 +90,11 @@ public final class Short extends Number implements Comparable<Short> private static final int MIN_CACHE = -128; private static final int MAX_CACHE = 127; private static Short[] shortCache = new Short[MAX_CACHE - MIN_CACHE + 1]; + static + { + for (short i=MIN_CACHE; i <= MAX_CACHE; i++) + shortCache[i - MIN_CACHE] = new Short(i); + } /** * The immutable value of this Short. @@ -184,7 +189,7 @@ public final class Short extends Number implements Comparable<Short> */ public static Short valueOf(String s, int radix) { - return new Short(parseShort(s, radix)); + return valueOf(parseShort(s, radix)); } /** @@ -200,7 +205,7 @@ public final class Short extends Number implements Comparable<Short> */ public static Short valueOf(String s) { - return new Short(parseShort(s, 10)); + return valueOf(parseShort(s, 10)); } /** @@ -216,12 +221,8 @@ public final class Short extends Number implements Comparable<Short> { if (val < MIN_CACHE || val > MAX_CACHE) return new Short(val); - synchronized (shortCache) - { - if (shortCache[val - MIN_CACHE] == null) - shortCache[val - MIN_CACHE] = new Short(val); - return shortCache[val - MIN_CACHE]; - } + else + return shortCache[val - MIN_CACHE]; } /** @@ -260,7 +261,7 @@ public final class Short extends Number implements Comparable<Short> int i = Integer.parseInt(s, 10, true); if ((short) i != i) throw new NumberFormatException(); - return new Short((short) i); + return valueOf((short) i); } /** |