2009-09-04 77 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

相關問題