2009-09-04 6 views
13

Desidero utilizzare BigDecimal per rappresentare numeri arbitrari di precisione come i prezzi e gli importi in un'applicazione di trading a bassa latenza con migliaia di ordini e report di esecuzione al secondo.In che modo l'utilizzo di BigDecimal potrebbe influire sulle prestazioni dell'applicazione?

Non eseguirò molte operazioni matematiche su di essi, quindi la domanda non riguarda le prestazioni del BigDecimal in sé, ma piuttosto il modo in cui grandi volumi di oggetti BigDecimal influenzerebbero le prestazioni dell'applicazione.

La mia preoccupazione è che un'enorme quantità di oggetti BigDecimal di breve durata metterà a dura prova un GC e si tradurranno in pause più grandi di Stop-The-World nel raccoglitore CMS - e questo è sicuramente ciò che vorrei evitare.

Potete confermare le mie preoccupazioni e suggerire alternative all'utilizzo di BigD? Inoltre, se pensi che le mie preoccupazioni siano sbagliate, ti preghiamo di spiegarne il motivo.

Aggiornamento:

Grazie per tutti coloro che hanno risposto. Ora sono convinto che l'utilizzo di BigDecimal danneggerà la latenza della mia applicazione (anche se ho ancora intenzione di misurarla).

Per il momento abbiamo deciso di rimanere con la soluzione "molto non-OOP" (ma senza colpo di precisione) - utilizzare due int s, uno per la mantissa e un altro per l'esponente. La logica alla base di questo è che le primitive vengono messe in pila, non heap, e quindi non sono soggette alla garbage collection.

risposta

12

Se si sta sviluppando un programma a bassa latenza di trading e si vuole veramente competere in termini di latenza, quindi BigDecimalnon è per voi, è così semplice come sembra. Nei casi in cui i microsecondi sono importanti, la creazione di oggetti e qualsiasi matematica decimale è semplicemente troppo costosa.

Direi che per quasi tutti gli altri, utilizzando BigDecimal è un gioco da ragazzi, perché avrà poco visibile impatto sulle prestazioni delle applicazioni.

Nei sistemi di latenza-critical prendere decisioni di trading, eventuali imprevedibili pause garbage-raccolta sono completamente out-of-the-domanda così mentre gli attuali algos garbage-raccolta sono fantastici in uso normale, non sono necessariamente appropriato quando un ritardo di 5 millisecondi può costare un sacco di soldi. Mi aspetterei che i sistemi di grandi dimensioni siano stati scritti in uno stile non-OOP, con oggetti piccoli o nulli usati a parte alcune stringhe internate (per codici e simili).

Avrete sicuramente bisogno di usare double (o anche float) e prendere la precisione colpito.

+0

Se BidD non è per me, allora cos'è? Io non uso i doppi (dato che porta molti nuovi problemi con i numeri in virgola mobile - i numeri con cui lavoro sono naturalmente decimali). – vtrubnikov

+2

+1 per aver affermato il punto chiave sulla competizione in termini di prestazioni. Come nella battuta sulla tigre e le scarpe da corsa, i numeri assoluti raramente contano molto, meglio di/peggio di ciò che conta. – soru

+0

@ valery_la99 - Ho aggiunto alla mia risposta –

7

Le JVM sono piuttosto buone al giorno d'oggi in termini di gestione della creazione e distruzione di oggetti di breve durata, quindi non è la preoccupazione di una volta.

Si consiglia di creare un modello di ciò che si desidera fare e misurare esso. Vale la pena molto più di qualsiasi risposta "teorica" ​​che potresti ottenere :-)

Guardando al tuo particolare dominio del problema, i sistemi simili su cui ho lavorato in passato funzionano molto bene usando il doppio per i dati vuoi usare BigDecimal e potrebbe valere la pena di riesaminare il tuo pensiero in quest'area. Una rapida occhiata a BigDecimal mostra che ha 5 o 6 campi, e il consumo extra di memoria su un singolo doppio può superare qualsiasi vantaggio di funzionalità che hai.

+0

Uno di questi campi è un 'BigInteger' (e uno dei campi di' BigInteger' è un 'int []') (Dom implementazione). –

+1

Buon punto. Ho notato anche una stringa, ma ho capito che è popolata solo durante l'invocazione di toString() –

+1

Trovo difficile credere che un sistema di trading basato su doppi per importi e prezzi possa mai funzionare, figuriamoci molto bene. La correttezza non è quasi un "vantaggio di funzionalità" che si dovrebbe mai riesaminare. –

5

BigDecimal ha prestazioni molto inferiori rispetto, ad esempio, long, double o addirittura Long. Che ciò possa fare una differenza significativa per le prestazioni della tua applicazione dipende dalla tua applicazione.

Suggerisco di trovare la parte più lenta dell'applicazione e di eseguire un test comparativo. È ancora abbastanza veloce? In caso contrario, si potrebbe voler scrivere una piccola classe immutabile contenente un singolo long, eventualmente controllando gli overflow.

1

Non sono sicuro quali sono le vostre esigenze, ma generalmente quando si fa un calcolo finanziario non si può permettersi il colpo di precisione causato dai tipi a virgola mobile. Di solito, l'accuratezza e il corretto arrotondamento sono più importanti dell'efficienza quando si tratta di soldi.
Se non si ha a che fare con le percentuali e tutti gli importi sono interi, è possibile utilizzare i tipi interi (int, long o anche BigInteger) con un significato di 0.01 della propria unità di valuta.
E anche se pensi di poterti colpire con precisione con il tipo double, può valere la pena provare prima con BigDecimal e verificare se è davvero lento per te.

2

La grande domanda è: in realtà sono necessari i calcoli decimali di precisione arbitrari? Se i calcoli vengono eseguiti solo per analizzare i dati e prendere decisioni in base a ciò, gli arrotondamenti e gli artefatti di rappresentazione binaria tra i bit meno significativi sono probabilmente irrilevanti per te; vai avanti e usa double (e analizza i tuoi algoritmi per numerical stability).

Se si stanno effettivamente effettuando transazioni in cui i numeri devono essere sommati e la precisione è assoluta, quindi double non è un'opzione. Forse puoi separare queste due parti della tua app e usare BigDecimal solo nella parte della transazione.

Se ciò non è possibile, allora sei praticamente sfortunato. Avresti bisogno di una libreria matematica BCD e non credo che Java ne abbia una. Puoi provare a scrivere da solo, ma ci sarà molto lavoro e il risultato potrebbe non essere ancora competitivo.

1

Lavoro per un team che esegue valutazioni delle prestazioni e ottimizzazioni sulle applicazioni, ha avuto un'applicazione che utilizzava recentemente Big Decimal Java. Sono stati osservati significativi problemi di prestazioni con l'utilizzo della memoria. Successivamente, siamo passati a Newton Raphson, che ci ha permesso di mantenere l'accuratezza con i calcoli e di mostrare prestazioni significativamente migliori con un grande decimale.

Giusto per aggiungere .. quando abbiamo usato raddoppia abbiamo visto una massiccia perdita di precisione come previsto

2

perché non si utilizza un lungo con un numero di casi implicita decimali? Ad esempio, supponiamo di avere 8 cifre decimali implicite, quindi 0,01 sarebbe 1000000.

Problemi correlati