如果BigDecimal是答案,那肯定是一个奇怪的问题
总览
许多开发人员已确定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是答案,那肯定是一个奇怪的问题相关推荐
- matlab使用矩形窗设计一个具有线性相位的低通数字滤波器,第七章习题与答案用矩形窗设计一个fir线性相位低通数字滤波器。已.doc...
第七章习题与答案用矩形窗设计一个fir线性相位低通数字滤波器.已 第七章习题与答案 用矩形窗设计一个FIR线性相位低通数字滤波器.已知 .求出并画出曲线. 分析:此题给定的是理想线性相位低通滤波器,故 ...
- 猫咪藏在哪个房间python_你家猫咪喜欢藏在哪睡觉?这只猫咪选择了一个奇怪的地方...
嗨,大家好,这里是小仙女和猫的原创文章,欢迎大家关注哦!你家猫咪喜欢藏在哪睡觉?这只猫咪选择了一个奇怪的地方. 猫咪的性格独立,情绪喜怒无常,一举一动经常不按章法来,它们的行为总是让人猜不透,即使是养 ...
- dedecms在linux主机下的一个奇怪错误
扬帆blog原创文章,转载请保留原地址:http://www.wesoho.com/article/asp/2874.htm dedecms上传到linux空间后遇到一个问题,所有header转向失效 ...
- 古堡算式 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA
/** 古堡算式福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!"华生:&quo ...
- 古堡算式(福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA)
/*** * 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:ABCDE * ? = EDCBA他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!"华生:" ...
- 古堡算式_经典的全排列问题(福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA 他对华生说:“ABCDE应该代表不同的数字,问号也代表某个数字!” 华生:“我猜也)
题目描述 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA 他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!" 华生:&quo ...
- 昨天发现了浏览器显示文字不全的一个奇怪的问题
昨天发现了一个关于浏览器显示的一个奇怪的问题没有得到解决,在这里发表一个疑问希望能够尽早找到答案, 现象是这样的,我们公司一个网站网站本身没有什么显示问题,也就是说在公司所有的电脑上浏览器显示都是正常 ...
- MinGW 和 MSVC 下,使用 FILE 类型的一个奇怪的问题
今天遇到一个奇怪的问题. 开发环境: 1. Eclipse CDT,使用 MinGW 的 gcc 编译器和函数库 2. Visual Studio 2008 问题描述: 在 eclipse cdt 中 ...
- java线程未执行完成,java线程测试-一个奇怪的景况-执行未完成直接结束了
java线程测试-一个奇怪的状况-执行未完成直接结束了 import org.junit.Test; /** * 同步线程测试 * @author jview * */ public class te ...
最新文章
- 【转】strlen源码
- 电脑不读u盘怎么解决_电脑无法识别U盘解决方法
- boost::math模块计算 Bessel、Neumann 和 Airy 函数的零点的测试程序
- Hive SQL子句中 group by 1 是什么意思?
- VS中修改站点运行方式(集成 Or 经典)
- deepfashion 深度学习_基于Alluxio加速混合云下的Intel Analytics Zoo开源深度学习平台...
- java gson_Java 中 Gson的使用
- NHibernate3.2+Asp.net MVC3+Extjs 4.0.2项目实践(二): NHibernate数据访问层实现
- enum中使用中文 unity_自定义Unity材质Inspector之枚举类型(Enum)
- 怪不得知乎急着招前端开发.
- 1.1 项目过程中遇到date类型插入数据库的问题及解决方法
- 点击 tomcat9.exe闪退 问题的解决方法
- R数据分析:混合效应模型的可视化解释,再不懂就真没办法
- 支付宝小程序获取用户手机号php,小程序登录、获取用户信息、手机号
- win7工作组计算机无法连接打印机,win7无法访问共享打印机怎么解决
- ansible 远程启动程序ansible结束后程序也被关闭
- 基于麒麟座开发板2.0的MQTT实现例程
- 阿昆的Java学习日记Day2
- cups ipp oracle,CUPS cups/ipp.c空指针引用拒绝服务漏洞
- Jmeter脚本两种录制方式
热门文章
- React中的方法调用
- mybatis的$和#详解分析
- java中public private_java中public、private、protected区别
- AQS的细节--自用,非正常教程
- HDU1176(DP)
- 动态资源Servlet接口
- aws上负载均衡器标组端口_AWS CloudFormation:目标组没有关联的负载均衡器
- aws lambda_跑来跑去:假人与AWS Lambda的第一次接触
- async 打包异常_重新打包流中的异常
- 怎样编写测试类测试分支_编写干净的测试–天堂中的麻烦