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

时间:2009-09-04 08:52:29

标签: java performance bigdecimal

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

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

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

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

更新

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

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

7 个答案:

答案 0 :(得分:13)

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

我认为,对于几乎其他人来说,使用BigDecimal是明智之举,因为它对应用程序性能几乎没有可见影响。

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

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

答案 1 :(得分:7)

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

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

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

答案 2 :(得分:5)

BigDecimal的效果确实比longdouble甚至Long低很多。这是否会对您的应用程序的性能产生重大影响取决于您的应用程序。

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

答案 3 :(得分:3)

最大的问题是:你实际上需要任意精确的十进制计算吗?如果仅进行计算以分析数据并基于此进行决策,则最低有效位中的舍入和二进制表示伪像可能与您无关;然后继续使用double(并分析您的算法numerical stability)。

如果您实际上正在进行数字必须加起来且精确度非常重要的事务,则double不是一个选项。也许您可以将应用的这两部分分开,并仅在事务部分中使用BigDecimal

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

答案 4 :(得分:2)

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

只是添加..当我们使用双打时,我们看到了预期的大量精度损失