为什么
result += Double.parseDouble(numberAsString)
result
是double
原语,慢于
result = result.add(new BigDecimal(numberAsStrings))
result
是BigDecimal
?
基准:
@Setup
public void beforeEach() {
numbersAsStrings = new String[NUMBER_COUNT];
double currentNumber = 1;
for (int i = 0; i < NUMBER_COUNT; i++) {
numbersAsStrings[i] = String.valueOf(currentNumber);
currentNumber += 0.1;
}
}
@Benchmark
public double addUpDoublesParsedFromString() {
double result = 0;
for (int i = 0; i < numbersAsStrings.length; i++) {
result += Double.parseDouble(numbersAsStrings[i]);
}
return result;
}
@Benchmark
public BigDecimal addUpBigDecimalsFromString() {
BigDecimal result = new BigDecimal(0);
for (int i = 0; i < numbersAsStrings.length; i++) {
result = result.add(new BigDecimal(numbersAsStrings[i]));
}
return result;
}
由于原语通常比非原语具有更快的计算声誉,因此结果令人惊讶(至少对我而言):
Benchmark Mode Samples Score Score error Units
t.n.b.n.BigDecimalVsDouble.addUpDoublesParsedFromString thrpt 4 484.070 59.905 ops/s
t.n.b.n.BigDecimalVsDouble.addUpBigDecimalsFromString thrpt 4 1024.567 170.329 ops/s
用于添加BigDecimals的1024.567 ops / s,但使用原语(在JMH中进行基准测试)仅添加484.070 ops / s。
为什么会这样?如果有一种方法可以优化从字符串中解析的double
原语的添加超出BigDecimal
的速度,请在答案中包含此内容。
答案 0 :(得分:1)
你真的在做两件事。 PARSING和ADDING,但你指责原始的加法更慢[如果你真的剖析了你的初始问题和你的评论,“因为原语通常比非原语更快地得到COMPUTING的声誉,结果令人惊讶(至少对我而言) ):“]。
也许添加操作不是double的慢速操作。也许对原语进行解析的速度较慢,而原语的添加速度更快。我会尝试更多基准测试,如下面的
double[] doubleValues;
BigDecimal[] bdValues;
@Setup
public void beforeEach() {
numbersAsStrings = new String[NUMBER_COUNT];
doubleValues = new double[NUMBER_COUNT];
bdValues = new BigDecimal[NUMBER_COUNT];
double currentNumber = 1;
for (int i = 0; i < NUMBER_COUNT; i++) {
numbersAsStrings[i] = String.valueOf(currentNumber);
doubleValues[i] = Double.parseDouble(numbersAsStrings[i]);
bdValues[i] = new BigDecimal(numbersAsStrings[i]);
currentNumber += 0.1;
}
}
//additional benchmarks
@Benchmark
public double addUpDoubles() {
double result = 0;
for (int i = 0; i < numbersAsStrings.length; i++) {
result += doubleValues[i];
}
return result;
}
@Benchmark
public BigDecimal addUpBigDecimals() {
BigDecimal result = new BigDecimal(0);
for (int i = 0; i < numbersAsStrings.length; i++) {
result = result.add(bdValues[i]);
}
return result;
}
@Benchmark
public void doublesParsedFromString() {
for (int i = 0; i < numbersAsStrings.length; i++) {
Double d = Double.parseDouble(numbersAsStrings[i]);
}
}
@Benchmark
public void bigDecimalsParsedFromString() {
for (int i = 0; i < numbersAsStrings.length; i++) {
BigDecimal bd = new BigDecimal(numbersAsStrings[i]);
}
}
//original benchmarks-----------------------
@Benchmark
public double addUpDoublesParsedFromString() {
double result = 0;
for (int i = 0; i < numbersAsStrings.length; i++) {
result += Double.parseDouble(numbersAsStrings[i]);
}
return result;
}
@Benchmark
public BigDecimal addUpBigDecimalsFromString() {
BigDecimal result = new BigDecimal(0);
for (int i = 0; i < numbersAsStrings.length; i++) {
result = result.add(new BigDecimal(numbersAsStrings[i]));
}
return result;
}
还要考虑较短的数字可能会快速解析BigDecimal,而较长的数字可能不会。我会尝试使用不同数字范围的基准