java - 创建多个 "throwaway"对象是否影响性能

标签 java optimization

例子:

是这样的

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。在表面之下,两种 操作、formatparseDouble 都会创建临时对象来完成它们的工作。他们的实现者没有理由担心它们,因为将 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/

相关文章:

java - eclipse /tomcat : deploy doesn't work any more (ClassNotFoundException)

java - Java 7 和 8 中的 32 位堆优化

javascript - 将 javascript 合并到一个文件中

optimization - 随机爬山与首选爬山算法

Python保持排序数据的最有效方法

java - 如何创建单个 SharedPreferences 然后创建不同的文件?

java - 从 Web 服务响应中删除自定义标签

java - 使用 socialauth 从 foursquare 成功重定向后 url 中的额外字符

c++ - 如何创建 4096 对齐表[x][4096]

大型网站的php&mysql分页脚本