以给定的精度快速将字符串转换为字符串
我需要以给定的精度将double转换为字符串。String.format("%.3f",
value)
(或DecimalFormat)可以完成这项工作,但基准测试显示,即使Double.toString
转换速度不是非常快(在我的计算机上转换一百万个数字,大约需要1-3秒),它的速度仍然很慢。
有什么更好的方法吗?
更新:基准化结果
从0到1000000的随机数,结果是以毫秒为单位的操作数(Java 1.7.0_45)
Benchmark Mean Mean error Units
String_format 747.394 13.197 ops/ms
BigDecimal_toPlainString 1349.552 31.144 ops/ms
DecimalFormat_format 1890.917 28.886 ops/ms
Double_toString 3341.941 85.453 ops/ms
DoubleFormatUtil_formatDouble 7760.968 87.630 ops/ms
SO_User_format 14269.388 168.206 ops/ms
更新:
Java 10 + Ryu
Mode Cnt Score Error Units
String_format thrpt 20 998.741 ± 52.704 ops/ms
BigDecimal_toPlainString thrpt 20 2079.965 ± 101.398 ops/ms
DecimalFormat_format thrpt 20 2040.792 ± 48.378 ops/ms
Double_toString thrpt 20 3575.301 ± 112.548 ops/ms
DoubleFormatUtil_formatDouble thrpt 20 7206.281 ± 307.348 ops/ms
ruy_doubleToString thrpt 20 9626.312 ± 285.778 ops/ms
SO_User_format thrpt 20 17143.901 ± 1307.685 ops/ms
-
免责声明: 我只建议您在绝对需要速度的情况下使用此功能。
在我的机器上,以下代码可以在约130毫秒内完成100万次转换:
private static final int POW10[] = {1, 10, 100, 1000, 10000, 100000, 1000000}; public static String format(double val, int precision) { StringBuilder sb = new StringBuilder(); if (val < 0) { sb.append('-'); val = -val; } int exp = POW10[precision]; long lval = (long)(val * exp + 0.5); sb.append(lval / exp).append('.'); long fval = lval % exp; for (int p = precision - 1; p > 0 && fval < POW10[p]; p--) { sb.append('0'); } sb.append(fval); return sb.toString(); }
所提供的代码有几个缺点:它只能处理有限范围的
doubles
,而不能处理NaN。前者可以通过扩展POW10
数组来解决(但只能部分解决)。后者可以在代码中显式处理。