如何使用BigDecimal会影响应用程序性能?

我想使用BigDecimal来表示低延迟交易应用程序中的任意精度数字,如价格和金额,每秒有数千个订单和执行报告。

我不会对它们进行很多数学运算,所以问题不在于BigDecimal本身的性能,而在于大量BigDecimal对象会如何影响应用程序的性能。

我担心的是,大量短命的BigDecimal对象会给GC带来压力并导致CMS收集器中更大的Stop-The-World暂停 – 这绝对是我想要避免的。

您能否确认我的疑虑并建议使用BigD的替代方案? 此外,如果您认为我的担忧是错误的 – 请解释原因。

更新

感谢所有回答的人。 我现在确信使用BigDecimal会损害我的应用程序的延迟(即使我仍然计划测量它)。

目前我们决定坚持使用“非常非OOP”解决方案(但没有精确命中) – 使用两个int ,一个用于尾数,另一个用于指数。 这背后的基本原理是基元放在堆栈上,而不是堆,因此不受垃圾收集的影响。

如果你正在开发一个低延迟的交易程序,并且你真的想要在延迟方面竞争 ,那么BigDecimal 不适合你 ,它就是那么简单。 微秒很重要,对象创建和任何十进制数学都太贵了。

我认为对于几乎所有人来说,使用BigDecimal是不费脑子的,因为它对应用程序性能几乎没有明显的影响。

在制定交易决策的延迟关键系统中, 任何不可预测的垃圾收集暂停都是完全没有问题的,因此当前的垃圾收集算法在正常使用中非常棒,当延迟5毫秒时它们不一定合适。花了你很多钱。 我希望大型系统是以非OOP风格编写的,除了一些实际的字符串(代码等)之外几乎没有使用任何对象。

你肯定需要使用double (甚至是float )并获得精确度。

JVM现在在处理短期对象的创建和销毁方面非常好,所以这不是曾经的担心。

我建议建立一个你想做的模型,并测量它。 这比你可能获得的任何“理论”答案值得多:-)

看看你的特定问题领域,过去我曾经使用的类似系统使用双打来处理你想要使用BigDecimal的数据,并且值得重新审视你在这方面的想法。 粗略地看一眼BigDecimal显示它有5或6个字段,而单个双倍的额外内存消耗可能超过你拥有的任何function优势。

BigDecimal性能远低于longdouble或甚至Long 。 这是否会对您的应用程序的性能产生重大影响取决于您的应用程序。

我建议找到你应用程序中最慢的部分并对其进行比较测试。 它还够快吗? 如果没有,您可能希望编写一个包含单个long的小型不可变类,可能会检查溢出。

最大的问题是:你真的需要任意精确的十进制计算吗? 如果仅进行计算以分析数据并基于此进行决策,那么最低有效位中的舍入和二进制表示工件可能与您无关; 继续使用double (并分析算法的数值稳定性 )。

如果你实际上做的事情是数字必须加起来并且精确度绝对重要,那么double不是一个选项。 也许您可以将应用程序的这两部分分开,并仅在事务部分中使用BigDecimal

如果那是不可能的,那么你几乎没有运气。 你需要一个BCD数学库,我认为Java没有。 你可以尝试编写自己的,但这将是很多工作,结果可能仍然没有竞争力。

为什么不使用带有隐含的十进制数的长数? 例如,假设您有8个小数位隐含,那么0.01将是1000000。

我不确定您的要求是什么,但通常在进行财务计算时,无法承受由浮点类型引起的精度损失。 通常,准确和适当的舍入比处理钱时的效率更重要。
如果您不必处理百分比并且所有金额都是整数,则可以使用整数类型(int,long或甚至BigInteger),其中一个含义为您的货币单位的0.01。
即使你认为你可以买到double类型的精确度,也许值得首先尝试使用BigDecimal并检查它是否真的对你来说很慢。

我为一个对应用程序进行性能评估和优化的团队工作,最近有一个应用程序正在使用Java Big Decimal。 内存利用率存在严重的性能问题。 我们后来切换到Newton Raphson,它允许我们通过计算保持准确性,并显示出更好的性能到大十进制。

只是补充..当我们使用双打时,我们看到了预期的大幅度损失