以给定的精度快速将字符串转换为字符串

发布于 2021-01-29 19:43:52

我需要以给定的精度将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
关注者
0
被浏览
118
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    免责声明: 我只建议您在绝对需要速度的情况下使用此功能。

    在我的机器上,以下代码可以在约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数组来解决(但只能部分解决)。后者可以在代码中显式处理。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看