2009-09-04 127 views
13

我想使用BigDecimal在低延迟交易应用程序中表示任意精确数字,例如价格和金额,每秒有数千个订单和执行报告。如何使用BigDecimal会影响应用程序性能?

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

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

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

更新

感谢所有谁回答。我现在确信使用BigDecimal会伤害我的应用程序的延迟(尽管我仍然计划对它进行测量)。

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

回答

12

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

我认为,对于几乎大家一样,使用BigDecimal是想都不用想,因为它会对应用程序的性能一点可见影响。

在作出交易决定延迟关键系统,任何不可预知的垃圾收集暂停是完全乱了,问题因此而目前的垃圾收集交易算法是在正常使用太棒了,他们不一定在适当的时候延迟5毫秒可能会花费你很多钱。我希望大型系统是以非OOP风格编写的,很少或根本没有使用某些实体字符串(代码等)。

你一定会需要使用double(甚至float),并采取命中精度。

+0

如果BidD不适合我,那么是什么?我不使用双打(因为它带来了浮点数的许多新问题 - 我使用的数字自然是小数)。 – vtrubnikov 2009-09-04 09:43:07

+2

+1表示竞争表现的关键点。正如在关于老虎和跑步鞋的笑话中,绝对数字很少有什么重要的,比重要的还要好。 – soru 2009-09-04 09:53:18

+0

@ valery_la99 - 我已添加到我的答案 – 2009-09-04 10:09:21

7

如今,在处理短暂对象的创建和销毁方面,JVM是相当不错的,所以这不是曾经的担忧。

我会推荐建立一个你想做的模型,并且测量它。这将比任何'理论'答案,你可能会得到更多的价值:-)

看看你的特定问题领域,类似的系统,我在过去的工作很好,使用双打数据你想使用BigDecimal,可能值得重新审视你在这方面的想法。粗略浏览一下BigDecimal显示它有5或6个字段,并且单个double内存占用的额外内存可能会超过您拥有的任何功能优势。

+0

其中一个领域是'BigInteger'(和的领域之一'BigInteger'是'INT []')(孙实现)。 – 2009-09-04 09:16:04

+1

好点。我也注意到在有一个字符串,但我明白,一个toString()调用 – 2009-09-04 09:20:01

+1

我觉得很难相信,基于双打量和价格的交易系统都不能在所有的工作,更谈不上很好期间唯一的填充。正确性很难说是“功能性利益”,一要不断重新审视。 – 2009-09-04 10:12:44

5

BigDecimal确实具有比例如long,double或甚至Long低得多的性能。这是否会对应用程序的性能产生重大影响取决于您的应用程序。

我建议找到你的应用程序的最慢的部分,并做一个比较测试。它还足够快吗?如果没有,你可能想编写一个包含一个单独的long的小型不可变类,可能检查溢出。

1

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

2

最大的问题是:你其实需要任意精度小数计算?如果计算仅用于分析数据并基于此进行决策,则最不重要位中的舍入和二进制表示伪像可能与您无关;只需继续并使用double(并分析您的算法numerical stability)。

如果你实际做其中的数字必须加起来的交易和事项精度绝对,那么double是不是一种选择。也许你可以分开你的应用程序的这两部分,并只在交易部分使用BigDecimal

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

1

我的团队,开展对应用程序的性能评估和优化工作,有一个应用程序最近,在使用Java大小数。在内存使用情况下观察到显着的性能问题。后来我们转向了牛顿拉夫森,这让我们能够保持计算的准确性,并且显示出对大数小数的显着改善。

我想补充..当我们用双打,我们看到在精度巨大的损失预期

2

你为什么不使用一个长着的小数情况下隐含多少?例如,假设你有8位小数暗示,则0.01将是1000000

相关问题