Как использование BigDecimal повлияет на производительность приложения?

Я хочу использовать BigDecimal для представления чисел произвольной точности, таких как цены и суммы, в торговом приложении с малой задержкой и тысячами ордеров и отчетов об исполнении в секунду.

Я не буду выполнять с ними много математических операций, поэтому вопрос не в производительности BigDecimal как таковой, а скорее в том, как большие объемы объектов BigDecimal повлияют на производительность приложения.

Меня беспокоит то, что огромное количество короткоживущих объектов BigDecimal создаст нагрузку на GC и приведет к большим паузам Stop-The-World в сборщике CMS - и это определенно то, чего я хотел бы избежать.

Не могли бы вы подтвердить мои опасения и предложить альтернативы использованию BigD? Кроме того, если вы считаете, что мои опасения ошибочны, объясните, почему.

Обновление:

Спасибо всем, кто ответил. Теперь я убежден, что использование BigDecimal уменьшит задержку моего приложения (хотя я все еще планирую ее измерить).

На данный момент мы решили придерживаться "очень не-ООП" решения (но без повышения точности) - использовать две int, одну для мантиссы и другую для экспоненты. Причина этого в том, что примитивы помещаются в стек, а не в кучу, и, следовательно, не подлежат сборке мусора.


person vtrubnikov    schedule 04.09.2009    source источник


Ответы (7)


Если вы разрабатываете торговую программу с малой задержкой и действительно хотите конкурировать с точки зрения задержки, то BigDecimal не для вас, это так просто. Там, где важны микросекунды, создание объектов и любая десятичная математика слишком дороги.

Я бы сказал, что для почти всех остальных использование BigDecimal не составляет труда, потому что это будет иметь мало видимого влияния на производительность приложения.

В критически важных системах, принимающих торговые решения, любые непредсказуемые паузы для сборки мусора совершенно исключены, поэтому, хотя текущие алгоритмы сборки мусора фантастически хороши при обычном использовании, они не обязательно подходят. когда задержка в 5 миллисекунд может стоить вам больших денег. Я ожидаю, что большие системы были написаны в стиле, отличном от ООП, с небольшим количеством объектов или без них, кроме некоторых интернированных строк (для кодов и т.п.).

Вам обязательно нужно будет использовать double (или даже float) и принять точный удар.

person oxbow_lakes    schedule 04.09.2009
comment
Если BidD не для меня, тогда что? Я не использую двойные числа (поскольку это приносит много новых проблем с числами с плавающей запятой, с которыми я работаю, естественно, десятичными). - person vtrubnikov; 04.09.2009
comment
+1 за указание ключевого момента о конкуренции по производительности. Как и в шутке про тигра и кроссовки, абсолютные цифры редко имеют большое значение, лучше/хуже, чем имеет значение. - person soru; 04.09.2009
comment
@valery_la99 - я добавил к своему ответу - person oxbow_lakes; 04.09.2009
comment
Альтернативу работе с Удвойте напрямую, используя плавный API вокруг него, который очень быстр, поскольку был разработан для тестирования финансовой стратегии. - person subes; 03.08.2015

В настоящее время JVM довольно хороши с точки зрения обработки создания и уничтожения недолговечных объектов, так что это не проблема, которая была раньше.

Я бы рекомендовал создать макет того, что вы хотите сделать, и измерить его. Это будет стоить намного больше, чем любые «теоретические» ответы, которые вы можете получить :-)

Глядя на вашу конкретную проблемную область, аналогичные системы, над которыми я работал в прошлом, очень хорошо работают, используя удвоения для данных, для которых вы хотите использовать BigDecimal, и, возможно, стоит пересмотреть свое мышление в этой области. Беглый взгляд на BigDecimal показывает, что у него 5 или 6 полей, а дополнительное потребление памяти по сравнению с одним двойным значением может перевесить любые преимущества функциональности, которые у вас есть.

person Brian Agnew    schedule 04.09.2009
comment
Одно из этих полей — BigInteger (а одно из полей BigIntegerint[]) (реализация Sun). - person Tom Hawtin - tackline; 04.09.2009
comment
Хорошая точка зрения. Я также заметил там строку, но я понимаю, что она заполняется только во время вызова toString() - person Brian Agnew; 04.09.2009
comment
Мне трудно поверить, что торговая система, основанная на удвоении сумм и цен, вообще может работать, не говоря уже о том, чтобы работать очень хорошо. Правильность вряд ли является преимуществом функциональности, которое когда-либо следует пересматривать. - person Michael Borgwardt; 04.09.2009
comment
@Michael - большинство систем, над которыми я работал, будут хранить условные значения / количества / денежные потоки и т. Д. Как двойники, без проблем. - person Brian Agnew; 04.09.2009
comment
Я предполагаю, что эти системы анализируют данные, а не фактически выполняют транзакции. - person Michael Borgwardt; 04.09.2009
comment
+1 за сборку и измерение. Слишком много написано, как будто общие тенденции применимы к каждой ситуации. - person CPerkins; 04.09.2009
comment
Хорошие комментарии. Двойники дают вам около 50 бит точности (около 17 знаков после запятой). Если вам нужно больше, большие целые числа, вероятно, работают лучше, чем создание их самостоятельно. - person Mike Dunlavey; 04.09.2009

BigDecimal имеет производительность намного ниже, чем, скажем, long, double или даже Long. Будет ли это иметь существенное значение для производительности вашего приложения, зависит от вашего приложения.

Я предлагаю найти самую медленную часть вашего приложения и провести сравнительный тест. Это все еще достаточно быстро? Если нет, вы можете написать небольшой неизменяемый класс, содержащий один long, возможно, проверяющий на переполнения.

person Tom Hawtin - tackline    schedule 04.09.2009

Большой вопрос: действительно ли вам нужны десятичные вычисления произвольной точности? Если вычисления выполняются только для анализа данных и принятия решений на их основе, то артефакты округления и двоичного представления среди младших битов, вероятно, не имеют для вас значения; просто используйте double (и проанализируйте свои алгоритмы на предмет числовой стабильности).

Если вы на самом деле выполняете транзакции, в которых числа должны складываться, а точность имеет абсолютное значение, то double не вариант. Возможно, вы можете разделить эти две части своего приложения и использовать BigDecimal только в части транзакции.

Если это невозможно, то вам в значительной степени не повезло. Вам понадобится математическая библиотека BCD, и я не думаю, что в Java она есть. . Можно попробовать написать свой, но это будет много работы и результат все равно может быть не конкурентоспособным.

person Michael Borgwardt    schedule 04.09.2009

почему бы вам не использовать long с подразумеваемым числом десятичных регистров? Например, предположим, что у вас подразумевается 8 знаков после запятой, тогда 0,01 будет 1000000.

person kms333    schedule 15.07.2011

Я не уверен, каковы ваши требования, но обычно при выполнении финансовых расчетов нельзя допустить снижения точности, вызванного типами с плавающей запятой. Обычно точность и правильное округление важнее, чем эффективность при работе с деньгами.
Если вам не нужно иметь дело с процентами и все суммы являются целыми числами, вы можете использовать целые типы (int, long или даже BigInteger) с один означает 0,01 вашей денежной единицы.
И даже если вы думаете, что можете позволить себе точность с типом double, возможно, стоит сначала попробовать с BigDecimal и проверить, действительно ли он для вас медленный.

person Tadeusz Kopec    schedule 04.09.2009

Я работаю в команде, которая занимается оценкой производительности и оптимизацией приложений. Недавно у меня было одно приложение, использующее Java Big Decimal. Наблюдались значительные проблемы с производительностью при использовании памяти. Позже мы перешли на Newton Raphson, что позволило нам сохранить точность вычислений и показало значительно лучшую производительность при работе с большими десятичными числами.

Просто добавлю... когда мы использовали удвоения, мы увидели огромную потерю точности, как и ожидалось.

person ryan    schedule 28.04.2011