2009-09-04 14 views
13

Quiero utilizar BigDecimal para representar números de precisión arbitrarios como precios y cantidades en una aplicación de negociación de baja latencia con miles de pedidos e informes de ejecución por segundo.¿Cómo afectaría BigDecimal el rendimiento de la aplicación?

No haré muchas operaciones matemáticas en ellas, por lo que la pregunta no es sobre el rendimiento del BigDecimal per se, sino sobre cómo los grandes volúmenes de objetos BigDecimal afectarían el rendimiento de la aplicación.

Mi preocupación es que la gran cantidad de objetos BigDecimal efímeros afectará a un GC y provocará pausas Stop-The-World más grandes en el colector CMS, y esto es definitivamente lo que me gustaría evitar.

¿Pueden confirmar mis dudas y sugerir alternativas al uso de BigD? Además, si cree que mis preocupaciones son incorrectas, explique por qué.

actualización:

Gracias por todos los que respondieron. Ahora estoy convencido de que el uso de BigDecimal perjudicará la latencia de mi aplicación (aunque aún planeo medirla).

Por el momento decidimos seguir con la solución "muy no-OOP" (pero sin precisión): use dos int s, uno para mantissa y otro para exponente. La razón detrás de esto es que los primitivos se colocan en la pila, no en el montón, y por lo tanto no están sujetos a la recolección de basura.

Respuesta

12

Si está desarrollando un programa de baja latencia de negociación y que realmente quiere competir en términos de latencia, entonces BigDecimalno es para usted, es tan simple como eso. Donde importan los microsegundos, la creación de objetos y cualquier cálculo decimal es demasiado costoso.

Yo diría que para casi todos los demás, utilizando BigDecimal es una obviedad, ya que tendrá poco visibles impacto en el rendimiento de las aplicaciones.

En los sistemas de latencia crítica toma de decisiones comerciales, cualquier pausas de recogida de basuras impredecibles son completamente fuera de la cuestión así que mientras los algos actuales de recolección de basura son fantásticos en el uso normal, no son necesariamente apropiado cuando un retraso de 5 milisegundos puede costarle mucho dinero. Me gustaría esperar que los sistemas de gran tamaño se escriban en un estilo que no sea de OOP, con poco o ningún objeto que se use aparte de algunas cadenas internas (para códigos y similares).

supuesto que va a necesita usar double (o incluso float) y tomar la precisión de impacto.

+0

Si BidD no es para mí, ¿qué es, entonces? No uso dobles (ya que traen un montón de nuevos problemas con coma flotante, los números con los que opero son decimales). – vtrubnikov

+2

+1 para establecer el punto clave sobre competir en el rendimiento. Como en el chiste sobre el tigre y las zapatillas para correr, los números absolutos rara vez importan mucho, mejor que/peor de lo que cuenta. – soru

+0

@ valery_la99 - He agregado mi respuesta –

7

Las JVM son bastante buenas hoy en día en términos de manipulación de la creación y destrucción de objetos efímeros, así que esa no es la preocupación que alguna vez fue.

Yo recomendaría construir una maqueta de lo que quiere hacer, y medida. Va a valer mucho más que cualquier respuesta "teórica" ​​que pueda obtener :-)

Al analizar el dominio de su problema en particular, los sistemas similares en los que he trabajado funcionan muy bien utilizando dobles para los datos desea utilizar BigDecimal para, y puede valer la pena volver a examinar su pensamiento en esta área. Una mirada rápida a BigDecimal muestra que tiene 5 o 6 campos, y el consumo de memoria adicional en un solo doble puede superar cualquier beneficio de funcionalidad que tenga.

+0

Uno de esos campos es un 'BigInteger' (y uno de los campos de' BigInteger' es un 'int []') (Sun implementación). –

+1

Buen punto. También noté una Cadena, pero entiendo que solo se llenó durante una invocación de toString() –

+1

Me resulta difícil creer que un sistema de comercio basado en duplicaciones de cantidades y precios pueda funcionar alguna vez, y mucho menos muy bien. La corrección no es un "beneficio de funcionalidad" que uno debería volver a examinar. –

5

BigDecimal tiene un rendimiento mucho menor que, por ejemplo, long, double o incluso Long. Si eso marcará una diferencia significativa en el rendimiento de su aplicación depende de su aplicación.

Sugiero encontrar la parte más lenta de su aplicación y hacer una prueba comparativa al respecto. ¿Todavía es lo suficientemente rápido? De lo contrario, es posible que desee escribir una pequeña clase inmutable que contenga un solo long, posiblemente verificando desbordamientos.

1

No estoy seguro de cuáles son sus requisitos, pero en general al hacer un cálculo financiero uno no puede permitirse el golpe de precisión causado por los tipos de coma flotante. Por lo general, la precisión y el redondeo adecuado es más importante que la eficiencia cuando se trata de dinero.
Si no tiene que tratar porcentajes y todas las cantidades son enteros, puede usar tipos enteros (int, largo o incluso BigInteger) con un significado 0.01 de su unidad monetaria.
E incluso si cree que puede permitirse el lujo de tener éxito con el tipo double, puede valer la pena probar primero con BigDecimal y comprobar si realmente va a disminuir la velocidad para usted.

2

La gran pregunta es: ¿realmente usted necesita cálculos decimales de precisión arbitraria? Si los cálculos solo se realizan para analizar los datos y tomar decisiones basadas en eso, entonces los artefactos de redondeo y representación binaria entre los bits menos significativos probablemente sean irrelevantes para usted; solo siga adelante y use double (y analice sus algoritmos para numerical stability).

Si en realidad está haciendo transacciones donde los números tienen que sumarse y la precisión es absoluta, entonces double no es una opción. Quizás pueda separar estas dos partes de su aplicación y usar BigDecimal solo en la parte de la transacción.

Si eso no es posible, no tiene suerte. Necesitarías una biblioteca de matemáticas BCD, y no creo que Java tenga una. Puede intentar escribir uno propio, pero será mucho trabajo y el resultado puede no ser competitivo.

1

Trabajo para un equipo que lleva a cabo evaluaciones de rendimiento y optimizaciones en las aplicaciones, recientemente tuve una aplicación que usaba Java Big Decimal. Se observaron problemas significativos de rendimiento con la utilización de la memoria. Más tarde cambiamos a Newton Raphson, lo que nos permitió mantener la precisión con los cálculos y mostramos un rendimiento significativamente mejor al decimal grande.

Sólo para añadir .. cuando utilizamos dobles vimos una pérdida masiva de exactitud como se esperaba

2

¿por qué no se utiliza mucho con un número de casos implícita decimales? Por ejemplo, supongamos que tiene 8 lugares decimales implicados, luego 0.01 sería 1000000.

Cuestiones relacionadas