例子:
是这样的
public double roundDecimal(double val) {
return Double.parseDouble(new DecimalFormat("#,##0.0").format(val));
}
double d1 = roundDecimal(val);
double d1 = roundDecimal(val);
double d1 = roundDecimal(val);
// A lot more of these...
考虑过不好的做法而不是这样的做法?
public double roundDecimal(double val, DecimalFormat dFormat) {
return Double.parseDouble(dFormat.format(val));
}
DecimalFormat dFormat = new DecimalFormat("#,##0.0");
double d1 = roundDecimal(val, dFormat);
double d1 = roundDecimal(val, dFormat);
double d1 = roundDecimal(val, dFormat);
// A lot more of these...
当然,不同之处在于,我不是一遍又一遍地创建 DecimalFormat 对象,而是只创建一次并重新使用它。我的想法是,垃圾收集器会确保这样的事情无关紧要,但我对它的了解还不足以确定。
最佳答案
您显然看错了方向。即使是“优化”变体
public double roundDecimal(double val, DecimalFormat dFormat) {
return Double.parseDouble(dFormat.format(val));
}
在每次调用时创建多个 对象。在 API 端,format
返回一个新的 String
实例,您将其传递给 parseDouble
。在表面之下,两种 操作、format
和parseDouble
都会创建临时对象来完成它们的工作。他们的实现者没有理由担心它们,因为将 double
格式化为十进制表示并将十进制表示解析为 double
的任务非常昂贵,以至于他们胜过一切。
这很容易被忽视,对于我们人类来说,十进制表示似乎是最自然的事情,但对于计算机来说,转换为十进制表示并返回是非常昂贵的。
但在您继续担心性能之前,您应该开始担心正确性。通常,将概念格式应用于 double
值不是一个好主意。由于它们的内部表示与十进制数根本不同,因此它们不能精确地表示十分之一。如果您想要那种可控的精度,BigDecimal
是完成这项工作的正确工具(是的,它们是对象……)。或者您使用 Formatter
的结果字符串进行打印或任何其他 UI 演示。
除此之外,通过使用格式字符串 "#,##0.0"
,您正在请求一个带有 grouping 分隔符的字符串 Double.parseDouble
不期望。此外,您正在应用当前用户区域设置的小数格式,因此如果不使用 .
作为小数点分隔符,则当值太小而无法分组时,操作将收支平衡。因此,对于英语语言环境,传递值 1234
足以破坏此方法,例如德国语言环境,它会破坏每个值。
解决方法是使用您用于格式化的相同格式进行解析:
public double roundDecimal(double val, DecimalFormat dFormat) {
try {
return dFormat.parse(dFormat.format(val)).doubleValue();
} catch (ParseException ex) {
throw new AssertionError(ex);
}
}
但这仍然会有灾难性的表现,不是因为创建了临时对象。
毕竟,如果您仍想使用 double
值而不是 BigDecimal
,解决方案很简单:
public double roundDecimal(double val) {
return Math.round(val*10)/10.0;
}
关于java - 创建多个 "throwaway"对象是否影响性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39457199/