提交 72e6dd7d 编写于 作者: B bpb

7032154: Performance tuning of sun.misc.FloatingDecimal/FormattedFloatingDecimal

Summary: Performance improvements for double/float -> String and decimal/hex String -> double/float conversions.
Reviewed-by: martin, iris
Contributed-by: NSergey Kuksenko &lt;sergey.kuksenko@oracle.com&gt;, Brian Burkhalter &lt;brian.burkhalter@oracle.com&gt;, Dmitry Nadezhin &lt;dmitry.nadezhin@oracle.com&gt;, Olivier Lagneau <olivier.lagneau@oracle.com>
上级 7d0a35a5
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -689,7 +689,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object.
*/
public AbstractStringBuilder append(float f) {
new FloatingDecimal(f).appendTo(this);
FloatingDecimal.appendTo(f,this);
return this;
}
......@@ -706,7 +706,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object.
*/
public AbstractStringBuilder append(double d) {
new FloatingDecimal(d).appendTo(this);
FloatingDecimal.appendTo(d,this);
return this;
}
......
......@@ -201,7 +201,7 @@ public final class Double extends Number implements Comparable<Double> {
* @return a string representation of the argument.
*/
public static String toString(double d) {
return new FloatingDecimal(d).toJavaFormatString();
return FloatingDecimal.toJavaFormatString(d);
}
/**
......@@ -509,7 +509,7 @@ public final class Double extends Number implements Comparable<Double> {
* parsable number.
*/
public static Double valueOf(String s) throws NumberFormatException {
return new Double(FloatingDecimal.readJavaFormatString(s).doubleValue());
return new Double(parseDouble(s));
}
/**
......@@ -545,7 +545,7 @@ public final class Double extends Number implements Comparable<Double> {
* @since 1.2
*/
public static double parseDouble(String s) throws NumberFormatException {
return FloatingDecimal.readJavaFormatString(s).doubleValue();
return FloatingDecimal.parseDouble(s);
}
/**
......
/*
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -203,7 +203,7 @@ public final class Float extends Number implements Comparable<Float> {
* @return a string representation of the argument.
*/
public static String toString(float f) {
return new FloatingDecimal(f).toJavaFormatString();
return FloatingDecimal.toJavaFormatString(f);
}
/**
......@@ -421,7 +421,7 @@ public final class Float extends Number implements Comparable<Float> {
* parsable number.
*/
public static Float valueOf(String s) throws NumberFormatException {
return new Float(FloatingDecimal.readJavaFormatString(s).floatValue());
return new Float(parseFloat(s));
}
/**
......@@ -456,7 +456,7 @@ public final class Float extends Number implements Comparable<Float> {
* @since 1.2
*/
public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.readJavaFormatString(s).floatValue();
return FloatingDecimal.parseFloat(s);
}
/**
......
......@@ -271,7 +271,7 @@ final class DigitList implements Cloneable {
* @param maximumFractionDigits The most fractional digits which should
* be converted.
*/
public final void set(boolean isNegative, double source, int maximumFractionDigits) {
final void set(boolean isNegative, double source, int maximumFractionDigits) {
set(isNegative, source, maximumFractionDigits, true);
}
......@@ -288,10 +288,11 @@ final class DigitList implements Cloneable {
*/
final void set(boolean isNegative, double source, int maximumDigits, boolean fixedPoint) {
FloatingDecimal fd = new FloatingDecimal(source);
boolean hasBeenRoundedUp = fd.digitsRoundedUp();
boolean allDecimalDigits = fd.decimalDigitsExact();
String digitsString = fd.toJavaFormatString();
FloatingDecimal.BinaryToASCIIConverter fdConverter = FloatingDecimal.getBinaryToASCIIConverter(source);
boolean hasBeenRoundedUp = fdConverter.digitsRoundedUp();
boolean allDecimalDigits = fdConverter.decimalDigitsExact();
assert !fdConverter.isExceptional();
String digitsString = fdConverter.toJavaFormatString();
set(isNegative, digitsString,
hasBeenRoundedUp, allDecimalDigits,
......@@ -305,9 +306,9 @@ final class DigitList implements Cloneable {
* @param allDecimalDigits Boolean value indicating if the digits in s are
* an exact decimal representation of the double that was passed.
*/
final void set(boolean isNegative, String s,
boolean roundedUp, boolean allDecimalDigits,
int maximumDigits, boolean fixedPoint) {
private void set(boolean isNegative, String s,
boolean roundedUp, boolean allDecimalDigits,
int maximumDigits, boolean fixedPoint) {
this.isNegative = isNegative;
int len = s.length();
char[] source = getDataChars(len);
......@@ -607,7 +608,7 @@ final class DigitList implements Cloneable {
/**
* Utility routine to set the value of the digit list from a long
*/
public final void set(boolean isNegative, long source) {
final void set(boolean isNegative, long source) {
set(isNegative, source, 0);
}
......@@ -620,7 +621,7 @@ final class DigitList implements Cloneable {
* If maximumDigits is lower than the number of significant digits
* in source, the representation will be rounded. Ignored if <= 0.
*/
public final void set(boolean isNegative, long source, int maximumDigits) {
final void set(boolean isNegative, long source, int maximumDigits) {
this.isNegative = isNegative;
// This method does not expect a negative number. However,
......
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -2807,10 +2807,10 @@ public final class Formatter implements Closeable, Flushable {
cal = Calendar.getInstance(l == null ? Locale.US : l);
cal.setTime((Date)arg);
} else if (arg instanceof Calendar) {
cal = (Calendar) ((Calendar)arg).clone();
cal = (Calendar) ((Calendar) arg).clone();
cal.setLenient(true);
} else if (arg instanceof TemporalAccessor) {
print((TemporalAccessor)arg, c, l);
print((TemporalAccessor) arg, c, l);
return;
} else {
failConversion(c, arg);
......@@ -3242,13 +3242,10 @@ public final class Formatter implements Closeable, Flushable {
int prec = (precision == -1 ? 6 : precision);
FormattedFloatingDecimal fd
= new FormattedFloatingDecimal(value, prec,
FormattedFloatingDecimal.Form.SCIENTIFIC);
= FormattedFloatingDecimal.valueOf(value, prec,
FormattedFloatingDecimal.Form.SCIENTIFIC);
char[] v = new char[MAX_FD_CHARS];
int len = fd.getChars(v);
char[] mant = addZeros(mantissa(v, len), prec);
char[] mant = addZeros(fd.getMantissa(), prec);
// If the precision is zero and the '#' flag is set, add the
// requested decimal point.
......@@ -3256,7 +3253,7 @@ public final class Formatter implements Closeable, Flushable {
mant = addDot(mant);
char[] exp = (value == 0.0)
? new char[] {'+','0','0'} : exponent(v, len);
? new char[] {'+','0','0'} : fd.getExponent();
int newW = width;
if (width != -1)
......@@ -3279,15 +3276,10 @@ public final class Formatter implements Closeable, Flushable {
int prec = (precision == -1 ? 6 : precision);
FormattedFloatingDecimal fd
= new FormattedFloatingDecimal(value, prec,
FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
// MAX_FD_CHARS + 1 (round?)
char[] v = new char[MAX_FD_CHARS + 1
+ Math.abs(fd.getExponent())];
int len = fd.getChars(v);
= FormattedFloatingDecimal.valueOf(value, prec,
FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
char[] mant = addZeros(mantissa(v, len), prec);
char[] mant = addZeros(fd.getMantissa(), prec);
// If the precision is zero and the '#' flag is set, add the
// requested decimal point.
......@@ -3306,22 +3298,17 @@ public final class Formatter implements Closeable, Flushable {
prec = 1;
FormattedFloatingDecimal fd
= new FormattedFloatingDecimal(value, prec,
FormattedFloatingDecimal.Form.GENERAL);
= FormattedFloatingDecimal.valueOf(value, prec,
FormattedFloatingDecimal.Form.GENERAL);
// MAX_FD_CHARS + 1 (round?)
char[] v = new char[MAX_FD_CHARS + 1
+ Math.abs(fd.getExponent())];
int len = fd.getChars(v);
char[] exp = exponent(v, len);
char[] exp = fd.getExponent();
if (exp != null) {
prec -= 1;
} else {
prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
}
char[] mant = addZeros(mantissa(v, len), prec);
char[] mant = addZeros(fd.getMantissa(), prec);
// If the precision is zero and the '#' flag is set, add the
// requested decimal point.
if (f.contains(Flags.ALTERNATE) && (prec == 0))
......@@ -3380,30 +3367,6 @@ public final class Formatter implements Closeable, Flushable {
}
}
private char[] mantissa(char[] v, int len) {
int i;
for (i = 0; i < len; i++) {
if (v[i] == 'e')
break;
}
char[] tmp = new char[i];
System.arraycopy(v, 0, tmp, 0, i);
return tmp;
}
private char[] exponent(char[] v, int len) {
int i;
for (i = len - 1; i >= 0; i--) {
if (v[i] == 'e')
break;
}
if (i == -1)
return null;
char[] tmp = new char[len - i - 1];
System.arraycopy(v, i + 1, tmp, 0, len - i - 1);
return tmp;
}
// Add zeros to the requested precision.
private char[] addZeros(char[] v, int prec) {
// Look for the dot. If we don't find one, the we'll need to add
......
......@@ -4,9 +4,7 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
......@@ -23,41 +21,41 @@
* questions.
*/
package sun.misc;
//package sun.misc;
/*
* A really, really simple bigint package
* tailored to the needs of floating base conversion.
*/
class FDBigInt {
class OldFDBigIntForTest {
int nWords; // number of words used
int data[]; // value: data[0] is least significant
public FDBigInt( int v ){
public OldFDBigIntForTest( int v ){
nWords = 1;
data = new int[1];
data[0] = v;
}
public FDBigInt( long v ){
public OldFDBigIntForTest( long v ){
data = new int[2];
data[0] = (int)v;
data[1] = (int)(v>>>32);
nWords = (data[1]==0) ? 1 : 2;
}
public FDBigInt( FDBigInt other ){
public OldFDBigIntForTest( OldFDBigIntForTest other ){
data = new int[nWords = other.nWords];
System.arraycopy( other.data, 0, data, 0, nWords );
}
private FDBigInt( int [] d, int n ){
private OldFDBigIntForTest( int [] d, int n ){
data = d;
nWords = n;
}
public FDBigInt( long seed, char digit[], int nd0, int nd ){
public OldFDBigIntForTest( long seed, char digit[], int nd0, int nd ){
int n= (nd+8)/9; // estimate size needed.
if ( n < 2 ) n = 2;
data = new int[n]; // allocate enough space
......@@ -189,10 +187,10 @@ class FDBigInt {
}
/*
* Multiply a FDBigInt by an int.
* Result is a new FDBigInt.
* Multiply a OldFDBigIntForTest by an int.
* Result is a new OldFDBigIntForTest.
*/
public FDBigInt
public OldFDBigIntForTest
mult( int iv ) {
long v = iv;
int r[];
......@@ -207,15 +205,15 @@ class FDBigInt {
p >>>= 32;
}
if ( p == 0L){
return new FDBigInt( r, nWords );
return new OldFDBigIntForTest( r, nWords );
} else {
r[nWords] = (int)p;
return new FDBigInt( r, nWords+1 );
return new OldFDBigIntForTest( r, nWords+1 );
}
}
/*
* Multiply a FDBigInt by an int and add another int.
* Multiply a OldFDBigIntForTest by an int and add another int.
* Result is computed in place.
* Hope it fits!
*/
......@@ -240,11 +238,11 @@ class FDBigInt {
}
/*
* Multiply a FDBigInt by another FDBigInt.
* Result is a new FDBigInt.
* Multiply a OldFDBigIntForTest by another OldFDBigIntForTest.
* Result is a new OldFDBigIntForTest.
*/
public FDBigInt
mult( FDBigInt other ){
public OldFDBigIntForTest
mult( OldFDBigIntForTest other ){
// crudely guess adequate size for r
int r[] = new int[ nWords + other.nWords ];
int i;
......@@ -265,14 +263,14 @@ class FDBigInt {
for ( i = r.length-1; i> 0; i--)
if ( r[i] != 0 )
break;
return new FDBigInt( r, i+1 );
return new OldFDBigIntForTest( r, i+1 );
}
/*
* Add one FDBigInt to another. Return a FDBigInt
* Add one OldFDBigIntForTest to another. Return a OldFDBigIntForTest
*/
public FDBigInt
add( FDBigInt other ){
public OldFDBigIntForTest
add( OldFDBigIntForTest other ){
int i;
int a[], b[];
int n, m;
......@@ -304,17 +302,17 @@ class FDBigInt {
int s[] = new int[ r.length+1 ];
System.arraycopy( r, 0, s, 0, r.length );
s[i++] = (int)c;
return new FDBigInt( s, i );
return new OldFDBigIntForTest( s, i );
}
return new FDBigInt( r, i );
return new OldFDBigIntForTest( r, i );
}
/*
* Subtract one FDBigInt from another. Return a FDBigInt
* Subtract one OldFDBigIntForTest from another. Return a OldFDBigIntForTest
* Assert that the result is positive.
*/
public FDBigInt
sub( FDBigInt other ){
public OldFDBigIntForTest
sub( OldFDBigIntForTest other ){
int r[] = new int[ this.nWords ];
int i;
int n = this.nWords;
......@@ -334,10 +332,10 @@ class FDBigInt {
}
assert c == 0L : c; // borrow out of subtract
assert dataInRangeIsZero(i, m, other); // negative result of subtract
return new FDBigInt( r, n-nzeros );
return new OldFDBigIntForTest( r, n-nzeros );
}
private static boolean dataInRangeIsZero(int i, int m, FDBigInt other) {
private static boolean dataInRangeIsZero(int i, int m, OldFDBigIntForTest other) {
while ( i < m )
if (other.data[i++] != 0)
return false;
......@@ -345,13 +343,13 @@ class FDBigInt {
}
/*
* Compare FDBigInt with another FDBigInt. Return an integer
* Compare OldFDBigIntForTest with another OldFDBigIntForTest. Return an integer
* >0: this > other
* 0: this == other
* <0: this < other
*/
public int
cmp( FDBigInt other ){
cmp( OldFDBigIntForTest other ){
int i;
if ( this.nWords > other.nWords ){
// if any of my high-order words is non-zero,
......@@ -405,7 +403,7 @@ class FDBigInt {
* as an integer, 0 <= q < 10.
*/
public int
quoRemIteration( FDBigInt S )throws IllegalArgumentException {
quoRemIteration( OldFDBigIntForTest S )throws IllegalArgumentException {
// ensure that this and S have the same number of
// digits. If S is properly normalized and q < 10 then
// this must be so.
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册