如果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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法思想_常见四种

文章目录常用算法思想描述穷举算法思想1. 基本思想2. 步骤3.实例递推算法1. 基本思想2. 步骤3. 实例递归算法1. 基本思想2. 步骤3. 实例1. 分治算法1. 基本思想2. 步骤3. 实例概率算法1. 基本思想2. 步骤3. 实例如果还有时间&#xff0c;将继续更新常用算法思想描述 穷举算法思…

[转] 做个自强不息的青年

人的出生和际遇本身造就了每个人的道路都不同&#xff0c;对于青年人来说&#xff0c;如何能够面对逆顺&#xff0c;如何面对起伏&#xff0c;如何能够正确设定理想并为之激发生命的火焰&#xff0c;在持续的奋斗中不断提升自我&#xff0c;自强不息而自立利他&#xff1f;在与…

commonJS — 全局操作(for Window)

for Window github: https://github.com/laixiangran/commonJS/blob/master/src/forWindow.js 代码 /*** Created by laixiangran on 2016/1/24* homepage&#xff1a;http://www.cnblogs.com/laixiangran/* for Window*/ (function() {var com window.COM window.COM || {}…

点击返回上一页失效

点击取消的时候&#xff0c;返回上一页&#xff0c;没有效果&#xff0c;仍然停留在当前页&#xff0c;还报500&#xff1b;改成window.history.go(-1)也不生效 代码&#xff1a; <button class"st-btn-normal st-btn-cancel cancle" onclick"javascript:wi…

如何通过7个Logback调整立即改善Java日志记录

基准测试可帮助您发现Logback在压力下的性能 日志记录对于服务器端应用程序是必不可少的&#xff0c;但这是有代价的。 令人惊讶的是&#xff0c;微小的更改和配置调整对应用程序的日志记录吞吐量有多大影响。 在这篇文章中&#xff0c;我们将根据每分钟的日志条目对Logback的性…

JS中的编码

今天发现我输入的中文变成了另外一种格式&#xff0c;查了一下&#xff0c;原来是转换成了数字编码。在这里介绍一下数字编码和base64&#xff0c;做个记录 1.出现原因&#xff1a;在开发中经常需要对用户输入的数据进行编码然后才能通过HTTP请求发送给后台&#xff0c;或者对…

commonJS — DOM操作(for DOM)

for DOM github: https://github.com/laixiangran/commonJS/blob/master/src/forDOM.js 代码 /*** Created by laixiangran on 2016/1/24* homepage&#xff1a;http://www.cnblogs.com/laixiangran/* for DOM*/(function(undefined) {var com window.COM window.COM || {};…

deMeer5_Attacker

SoccerCommand Player::deMeer5_Attacker(){SoccerCommand soc(CMD_ILLEGAL);if (WM->isBeforeKickOff()){if (formations->getFormation() ! FT_INITIAL || //不在开球的阵型 WM->getAgentGlobalPosition().getDistanceTo(WM->getStrategicPosition()) > 2.…

【Flutter】解决依赖版本冲突

为什么会存在版本依赖问题 我们在开发flutter项目中&#xff0c;常常会依赖第三方库。flutter依赖项越多&#xff0c;就越有可能出现依赖版本冲突。 Because new_trend depends on build_runner >0.9.0 which requires SDK version >2.0.0-dev.61 <3.0.0, version sol…

安装vue-cli时报错

今天用npm安装vue-cli时一直报错&#xff0c;后面百度说用cnpm重装&#xff0c;结果还是报错&#xff0c;后面找到一个博主的&#xff0c;说是vue升级的原因&#xff0c;vue init webpack hello-world 已经替换为 vue create hello-world npm install -g vue/cli-init # vue…

从JPA到Hibernate的旧版和增强型标识符生成器

JPA标识符生成器 JPA定义了以下标识符策略&#xff1a; 战略 描述 汽车 持久性提供程序选择基础数据库支持的最合适的标识符策略 身份 标识符由数据库IDENTITY列分配 序列 持久性提供程序使用数据库序列来生成标识符 表 持久性提供程序使用单独的数据库表来模拟序列对…

快速了解AngularJs HTTP响应拦截器

任何时候&#xff0c;如果我们想要为请求添加全局功能&#xff0c;例如身份认证、错误处理等&#xff0c;在请求发送给服务器之前或服务器返回时对其进行拦截&#xff0c;是比较好的实现手段。 angularJs通过拦截器提供了一个从全局层面进行处理的途径。 四种拦截器 实现 req…

U盘专杀工具,U盘防御软件,U盘病毒防火墙--UDiskSyS

近来闲聊无事&#xff0c;写了一款专门针对U盘的防御软件&#xff0c;U盘插入后自动扫描并清除病毒并还原被感染的文件。是常见的文件夹伪装病毒&#xff0c;死亡应答病毒&#xff0c;exe感染型病毒的克星。UDiskSyS不像那些所谓的正规杀毒软件遇到搞不定的病毒统统删除之&…

CenterNet算法笔记(目标检测论文)

论文名称&#xff1a;CenterNet: Keypoint Triplets for Object Detectiontection 论文链接&#xff1a;https://arxiv.org/abs/1904.08189 代码链接&#xff1a;https://github.com/Duankaiwen/CenterNet 简介 该论文是由中科院&#xff0c;牛津大学以及华为诺亚方舟实验室联合…

git提交代码时报错:nothing added to commit but untracked files present

原因&#xff1a; git没有把提交的文件加载进来&#xff0c;报红色的是需要提交的文件&#xff0c; 解决步骤&#xff1a; 用git add XXX(文件名) 把提示报红色的文件加上git commit -m “xx”git push -u origin master重新提交就可以了

VSS使用手册

1 VSS概述 版本控制是工作组软件开发中的重要方面&#xff0c;它能防止意外的文件丢失、允许反追踪到早期版本、并能对版本进行分支、合并和管理。在软件开发和您需要比较两种版本的文件或找回早期版本的文件时&#xff0c;源代码的控制是非常有用的。Visual SourceSafe 是一种…

语句和函数

1.for-in语句&#xff1a;是一种精准的迭代语句&#xff0c;可以用来枚举对象的属性。 2.label语句&#xff1a;在代码中添加标签&#xff0c;以便将来使用&#xff0c;由break和continue语句调用。3.with语句&#xff1a;将代码的作用域设置到一个特定的对象中。一般不建议过多…

服务器与客户端渲染(AngularJS与服务器端MVC)

关于服务器与客户端应用程序渲染的讨论很多。 虽然没有“一刀切”的解决方案&#xff0c;但我将尝试从不同的角度主张客户端&#xff08;特别是AngularJS&#xff09;。 首先是建筑。 建筑 做得好的架构已经明确定义了关注点分离&#xff08;SoS&#xff09; 。 在大多数情况下…

MySQL 数据类型简介 创建数据表及其字段约束

数据类型介绍 MySQL 数据类型分类 整型浮点型字符类型(char与varchar)日期类型枚举与集合具体数据类型见这篇博客 MySQL表操作中的约束 primary key 主键约束 非空唯一unique key 唯一约束not null 非空约束foreign key 外键约束创建表的的语法 CREATE TABLE[IF NOT EXISTS] tb…

elementUI的container布局设置全屏宽度

进用element UI的 container 布局&#xff0c;发现不能全屏铺满 添加了一行代码&#xff1a; .el-container{height:100%;padding:0;margin:0;width:100%;}发现高度占满全屏&#xff0c;但是宽度还没有 继续给 html,body加了 width&#xff1a;100%&#xff1b;还是没有任何…