15

BigDecimal を使用して、価格や金額などの任意の精度の数値を、毎秒数千の注文と約定レポートを持つ低レイテンシーの取引アプリケーションで表現したいと考えています。

それらに対して多くの数学演算を行うつもりはないので、問題は BigDecimal 自体のパフォーマンスではなく、BigDecimal オブジェクトのボリュームがアプリケーションのパフォーマンスにどの程度影響するかです。

私の懸念は、大量の短期間の BigDecimal オブジェクトが GC に負担をかけ、CMS コレクターで Stop-The-World の一時停止が大きくなるということです。これは間違いなく避けたいことです。

私の懸念を確認し、BigD を使用する代わりの方法を提案していただけますか? また、私の懸念が間違っていると思われる場合は、その理由を説明してください。

更新

答えてくれてありがとう。BigDecimal を使用すると、アプリケーションのレイテンシーが損なわれることがわかりました (まだ測定する予定ではありますが)。

当分の間、「非常に非 OOP」のソリューションを使用することにしました (ただし、精度への影響はありません) - 2 つintの を使用します。1 つは仮数用で、もう 1 つは指数用です。この背後にある理論的根拠は、プリミティブがヒープではなくスタックに配置されるため、ガベージ コレクションの対象にならないことです。

4

7 に答える 7

15

低レイテンシーの取引プログラムを開発していて、本当にレイテンシーの観点から競争したいのであれば、それはあなたのBigDecimal ためではありません、それはそれと同じくらい簡単です。マイクロ秒が重要な場合、オブジェクトの作成と小数の計算はコストがかかりすぎます。

他のほとんどの人にとって、アプリケーションのパフォーマンスに目に見えるBigDecimal影響はほとんどないため、使用するのは簡単です。

トレーディングを決定するレイテンシークリティカルなシステムでは予測できないガベージコレクションの一時停止は完全に問題外であるため、現在のガベージコレクションアルゴリズムは通常の使用では素晴らしいものですが、5ミリ秒の遅延が発生する可能性がある場合は必ずしも適切ではありません。あなたにたくさんのお金がかかります。大規模なシステムは非常に非OOPスタイルで記述されており、一部のインターン文字列(コードなど)を除いてオブジェクトはほとんどまたはまったく使用されていないと思います。

あなたは確かに使用してdouble(あるいはfloat)正確さのヒットを取る必要があります、さもなければlongすべての金額をセント、10分の1セントまたはサトシ(アカウントの最小単位が何であれ)で使用して測定する必要があります。

于 2009-09-04T09:26:35.757 に答える
8

最近の JVM は、存続期間の短いオブジェクトの作成と破棄を処理するという点で非常に優れているため、以前ほど心配する必要はありません。

やりたいことのモックアップを作成し、それを測定することをお勧めします。それは、あなたが得るかもしれない「理論的な」答えよりもはるかに価値があるでしょう:-)

あなたの特定の問題ドメインを見ると、私が過去に取り組んだ同様のシステムは、BigDecimal を使用するデータに double を使用して非常にうまく機能します。この分野であなたの考えを再検討する価値があるかもしれません。BigDecimal をざっと見てみると、5 つまたは 6 つのフィールドがあることがわかります。また、単一の double を超える余分なメモリ消費が、機能上の利点を上回っている可能性があります。

于 2009-09-04T08:55:28.130 に答える
5

BigDecimallongたとえば、、、doubleまたはよりもはるかに低いパフォーマンスを持っていますLong。それがアプリケーションのパフォーマンスに大きな違いをもたらすかどうかは、アプリケーションによって異なります。

アプリケーションの最も遅い部分を見つけて、それについて比較テストを行うことをお勧めします。それでも十分速いですか?そうでない場合は、単一の を含む小さな不変クラスを作成しlong、おそらくオーバーフローをチェックすることをお勧めします。

于 2009-09-04T09:15:07.870 に答える
4

大きな問題は、実際に任意精度の小数計算が必要かということです。計算がデータを分析し、それに基づいて決定を行うためだけに行われる場合、最下位ビットの丸めとバイナリ表現のアーティファクトはおそらく関係ありません。先に進んで使用してください(そして数値安定性doubleについてアルゴリズムを分析してください)。

数値を合計する必要があり、精度が絶対的に重要なトランザクションを実際に行っている場合doubleは、オプションではありません。おそらく、アプリのこれら 2 つの部分を分離BigDecimalして、トランザクション部分でのみ使用することができます。

それが不可能な場合は、ほとんど運がありません。BCD数学ライブラリが必要ですが、Javaにはないと思います。自分で書いてみることもできますが、それは大変な作業であり、結果はまだ競争力がないかもしれません.

于 2009-09-04T10:34:59.050 に答える
2

暗黙の小数点以下の桁数で long を使用しないのはなぜですか? たとえば、小数点以下 8 桁が暗示されている場合、0.01 は 1000000 になります。

于 2011-07-15T16:30:44.273 に答える
1

あなたの要件が何であるかはわかりませんが、一般的に財務計算を行う場合、浮動小数点型によって引き起こされる精度への影響を許容できません。通常、お金を扱うときは、正確さと適切な丸めが効率よりも重要です。
パーセンテージを扱う必要がなく、すべての金額が整数である場合は、通貨単位の 0.01 を意味する整数型 (int、long、または BigInteger) を使用できます。
また、タイプで正確なヒットを得る余裕があると思われる場合でも、double最初に BigDecimal を試して、本当に遅いかどうかを確認する価値があるかもしれません。

于 2009-09-04T10:25:15.047 に答える
1

私は、アプリケーションのパフォーマンス評価と最適化を行うチームで働いており、最近、Java Big Decimal を使用するアプリケーションが 1 つありました。メモリ使用率に関して重大なパフォーマンスの問題が観察されました。後にニュートン ラフソンに切り替えたことで、計算の精度を維持できるようになり、大きな小数に対するパフォーマンスが大幅に向上しました。

追加するだけです..ダブルを使用すると、予想どおり精度が大幅に低下しました

于 2011-04-28T14:51:20.257 に答える