总览

许多开发人员已确定BigDecimal是处理金钱的唯一方法。 通常,他们通过用BigDecimal替换double来确定错误或十个错误。 我对此没有说服力的是,也许他们可以解决double处理中的错误以及使用BigDecimal的额外开销。

根据我的比较,当被问到改善财务应用程序的性能时,我知道有时会删除BigDecimal(如果有的话)。 (通常不是造成延迟的最大原因,但是当我们修复系统时,它会升级为最严重的违规者)。

BigDecimal不能改善

BigDecimal有很多问题,因此请选择,但丑陋的语法也许是最糟糕的罪过。

  • BigDecimal语法是不自然的。
  • BigDecimal使用更多内存
  • BigDecimal创建垃圾
  • 对于大多数操作,BigDecimal的速度要慢得多(有例外)

以下JMH基准测试演示了BigDecimal的两个问题:清晰度和性能。

核心代码取两个值的平均值。

双重实现看起来像这样。 注意:需要使用四舍五入。

mp[i] = round6((ap[i] + bp[i]) / 2);

使用BigDecimal进行的相同操作不仅很长,而且还有很多样板代码需要导航

mp2[i] = ap2[i].add(bp2[i]).divide(BigDecimal.valueOf(2), 6, BigDecimal.ROUND_HALF_UP);

这会给您带来不同的结果吗? double的精度为15位,而数字远少于15位。 如果这些价格有17位数字,这将起作用,但对必须理解价格的穷人也不会起作用(即,它们永远不会变得难以置信的长)。

性能

如果您必须承担编码开销,通常这样做是出于性能方面的考虑,但这在这里没有意义。

基准测试 模式 样品 得分了 得分错误 单位
osMyBenchmark.bigDecimalMidPrice thrpt 20 23638.568 590.094 运算/秒
osMyBenchmark.doubleMidPrice thrpt 20 123208.083 2109.738 运算/秒

结论

如果您不知道如何使用双精度整数,或者您的项目要求使用BigDecimal,请使用BigDecimal。 但是,如果您有选择的话,不要仅仅认为BigDecimal是正确的选择。

编码

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.math.BigDecimal;
import java.util.Random;@State(Scope.Thread)
public class MyBenchmark {static final int SIZE = 1024;final double[] ap = new double[SIZE];final double[] bp = new double[SIZE];final double[] mp = new double[SIZE];final BigDecimal[] ap2 = new BigDecimal[SIZE];final BigDecimal[] bp2 = new BigDecimal[SIZE];final BigDecimal[] mp2 = new BigDecimal[SIZE];public MyBenchmark() {Random rand = new Random(1);for (int i = 0; i < SIZE; i++) {int x = rand.nextInt(200000), y = rand.nextInt(10000);ap2[i] = BigDecimal.valueOf(ap[i] = x / 1e5);bp2[i] = BigDecimal.valueOf(bp[i] = (x + y) / 1e5);}doubleMidPrice();bigDecimalMidPrice();for (int i = 0; i < SIZE; i++) {if (mp[i] != mp2[i].doubleValue())throw new AssertionError(mp[i] + " " + mp2[i]);}}@Benchmarkpublic void doubleMidPrice() {for (int i = 0; i < SIZE; i++)mp[i] = round6((ap[i] + bp[i]) / 2);}static double round6(double x) {final double factor = 1e6;return (long) (x * factor + 0.5) / factor;}@Benchmarkpublic void bigDecimalMidPrice() {for (int i = 0; i < SIZE; i++)mp2[i] = ap2[i].add(bp2[i]).divide(BigDecimal.valueOf(2), 6, BigDecimal.ROUND_HALF_UP);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(".*" + MyBenchmark.class.getSimpleName() + ".*").forks(1).build();new Runner(opt).run();}
}

翻译自: https://www.javacodegeeks.com/2014/07/if-bigdecimal-is-the-answer-it-must-have-been-a-strange-question.html

如果BigDecimal是答案,那肯定是一个奇怪的问题相关推荐

  1. matlab使用矩形窗设计一个具有线性相位的低通数字滤波器,第七章习题与答案用矩形窗设计一个fir线性相位低通数字滤波器。已.doc...

    第七章习题与答案用矩形窗设计一个fir线性相位低通数字滤波器.已 第七章习题与答案 用矩形窗设计一个FIR线性相位低通数字滤波器.已知 .求出并画出曲线. 分析:此题给定的是理想线性相位低通滤波器,故 ...

  2. 猫咪藏在哪个房间python_你家猫咪喜欢藏在哪睡觉?这只猫咪选择了一个奇怪的地方...

    嗨,大家好,这里是小仙女和猫的原创文章,欢迎大家关注哦!你家猫咪喜欢藏在哪睡觉?这只猫咪选择了一个奇怪的地方. 猫咪的性格独立,情绪喜怒无常,一举一动经常不按章法来,它们的行为总是让人猜不透,即使是养 ...

  3. dedecms在linux主机下的一个奇怪错误

    扬帆blog原创文章,转载请保留原地址:http://www.wesoho.com/article/asp/2874.htm dedecms上传到linux空间后遇到一个问题,所有header转向失效 ...

  4. 古堡算式 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA

    /** 古堡算式福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!"华生:&quo ...

  5. 古堡算式(福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA)

    /*** * 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!"华生:" ...

  6. 古堡算式_经典的全排列问题(福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA 他对华生说:“ABCDE应该代表不同的数字,问号也代表某个数字!” 华生:“我猜也)

    题目描述 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA 他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!" 华生:&quo ...

  7. 昨天发现了浏览器显示文字不全的一个奇怪的问题

    昨天发现了一个关于浏览器显示的一个奇怪的问题没有得到解决,在这里发表一个疑问希望能够尽早找到答案, 现象是这样的,我们公司一个网站网站本身没有什么显示问题,也就是说在公司所有的电脑上浏览器显示都是正常 ...

  8. MinGW 和 MSVC 下,使用 FILE 类型的一个奇怪的问题

    今天遇到一个奇怪的问题. 开发环境: 1. Eclipse CDT,使用 MinGW 的 gcc 编译器和函数库 2. Visual Studio 2008 问题描述: 在 eclipse cdt 中 ...

  9. java线程未执行完成,java线程测试-一个奇怪的景况-执行未完成直接结束了

    java线程测试-一个奇怪的状况-执行未完成直接结束了 import org.junit.Test; /** * 同步线程测试 * @author jview * */ public class te ...

最新文章

  1. 【转】strlen源码
  2. 电脑不读u盘怎么解决_电脑无法识别U盘解决方法
  3. boost::math模块计算 Bessel、Neumann 和 Airy 函数的零点的测试程序
  4. Hive SQL子句中 group by 1 是什么意思?
  5. VS中修改站点运行方式(集成 Or 经典)
  6. deepfashion 深度学习_基于Alluxio加速混合云下的Intel Analytics Zoo开源深度学习平台...
  7. java gson_Java 中 Gson的使用
  8. NHibernate3.2+Asp.net MVC3+Extjs 4.0.2项目实践(二): NHibernate数据访问层实现
  9. enum中使用中文 unity_自定义Unity材质Inspector之枚举类型(Enum)
  10. 怪不得知乎急着招前端开发.
  11. 1.1 项目过程中遇到date类型插入数据库的问题及解决方法
  12. 点击 tomcat9.exe闪退 问题的解决方法
  13. R数据分析:混合效应模型的可视化解释,再不懂就真没办法
  14. 支付宝小程序获取用户手机号php,小程序登录、获取用户信息、手机号
  15. win7工作组计算机无法连接打印机,win7无法访问共享打印机怎么解决
  16. ansible 远程启动程序ansible结束后程序也被关闭
  17. 基于麒麟座开发板2.0的MQTT实现例程
  18. 阿昆的Java学习日记Day2
  19. cups ipp oracle,CUPS cups/ipp.c空指针引用拒绝服务漏洞
  20. Jmeter脚本两种录制方式

热门文章

  1. React中的方法调用
  2. mybatis的$和#详解分析
  3. java中public private_java中public、private、protected区别
  4. AQS的细节--自用,非正常教程
  5. HDU1176(DP)
  6. 动态资源Servlet接口
  7. aws上负载均衡器标组端口_AWS CloudFormation:目标组没有关联的负载均衡器
  8. aws lambda_跑来跑去:假人与AWS Lambda的第一次接触
  9. async 打包异常_重新打包流中的异常
  10. 怎样编写测试类测试分支_编写干净的测试–天堂中的麻烦