Newsgroup: it.comp.java
Titolo: BigDecimal e prestazioni

Qualcuno conosce una alternativa a BigDecimal, ma a precisione fissa (pero' 
decimale, non FP binario)? Oppure una versione mutable di BigDecimal, oppure 
ancora una sorta di BigDecimalBuilder (String->StringBuilder) per evitare di 
fare troppe creazioni di oggetti temporanei?
La nostra applicazione sta attualmente usando BigDecimal, ma questo usa 
troppa memoria e troppa CPU.
Grazie,
Tommy

 troppa memoria e troppa CPU.
Per curiosità a cosa vi serve?
Qual'e' il range di valori che ti serve?
Puoi scriverti un DoubleLong o QuadrupleLong che estende Number se ti 
bastano 128, o 256 bit.
-- 
Andrea Francia
http://andreafrancia.blogspot.com/2008/05/schermare-le-remoteexception.html

 bastano 128, o 256 bit.
Volevo evitare di dovermi implementare io una versione di C# Decimal (128bit 
decimal number per calcoli finanziari).
Quote:
---------
decimal (C# Reference)
The decimal keyword denotes a 128-bit data type. Compared to floating-point 
types, the decimal type has a greater precision and a smaller range, which 
makes it suitable for financial and monetary calculations. The approximate 
range and precision for the decimal type are shown in the following table.
Remarks
...
The Decimal value type is appropriate for financial calculations requiring 
large numbers of significant integral and fractional digits and *no 
round-off errors*.
...
Tommy

bastano 128, o 256 bit.
Hummm... sono contrario a queste versioni "artigianali", anche perché
dubito molto che a prestazioni e consumi si riesca a fare meglio
rispetto a quanto già presente in libreria.
Sarebbe meglio capire qual è l'esigenza di base.
Comunque - e lo dico con una punta di cattiveria - se si cercano
prestazioni e consumi ridotti, forse certe parti di calcolo massivo
conviene riscriverle in un altro linguaggio.

decimal number per calcoli finanziari).
Non serve, perché le caratteristiche di Decimal di C# sono esattamente
le stesse di BigDecimal.

 decimal number per calcoli finanziari).
Guarda bene che dovrebbe esserci un tipo Currency in Java o simile.
Cercati financial calculation in java su google.


 un intero). 
Se vuole un numero a precisione fissa gli va bene un intero, poi se lo 
scala lui.


 scala lui.
gisto per il gusto di farlo, perchè BigDecimal afaik fa la stessa cosa.
-- 
 Fino all'anno scorso avevo un solo difetto. Ero presuntuoso.
http://softvalley.blogspot.com
http://www.flickr.com/photos/marko_po/

 le stesse di BigDecimal.
Ho gia' spiegato il problema, BigDecimal e' troppo lento e usa troppa 
memoria e troppi oggetti temporanei. Altrimenti andrebbe benissimo.
Poi le caratteristiche non sono le stesse C# e' 128bit, e BigDecimal a 
precisione arbitraria...
Tommy

 precisione arbitraria...
ma questo delle prestazioni è un problema teorico o realmente riscontrato?
quello della memoria non è imho un problema da porsi, il garbage 
collector può usare strategie che favoriscono l'eliminazione degli 
oggetti a vita breve.


 oggetti a vita breve.
Poi sembra che sia tanto furbo da riutilizzare la memoria appena 
rilasciata per il nuovo oggetto di memoria di dimensione uguale o minore.


 Cercati financial calculation in java su google.
Ho gia' cercato parecchio ma continiero'...
Grazie,
Tommy

 conviene riscriverle in un altro linguaggio.
Concorde... ma purtroppo il cliente ha insistito che si utilizzasse Java. 
Sono stati fatti vari "proof of concepts" in vari linguaggi e nonostante 
Java non fosse quello migliore, il cliente ha cmq deciso di usare Java. (per 
vari motivi).
Tommy

 breve.
e' un problema delle prestazioni e' riscontrato. Il problema della memoria 
e' da porsi poi in quanto il sistema, per vari motivi, non girera' su di una 
VM normale e dobbiamo limitare al massimo il numero di allocazioni di 
memoria non necessarie. BigDecimal attualmente e' la cosa che usa piu' 
memoria di tutto il sistema.
Tommy

 


 memoria di tutto il sistema.
a questo punto io penserei a qualcosa diverso da java.


 almeno 8 decimali e, mi sono sbagliato, 10 intere non credo piu' bastino.
I requisiti dovevano contenere le specifiche delle prestazioni minime 
richieste e delle specifiche sui limiti del software.
Se non le contengono c'e' qualcosa da migliorare nel processo di 
ingegneria dei requisiti.
Se le specifiche possono cambiare in modo non gestito c'e' qualcosa da 
da migliorare nel modo di gestire il progetto.


scala lui.
Il BigDecimal va benissimo, anche se vuoi la precisione fissa.

precisione arbitraria...
Non c'entra niente la dimensione in bit con la precisione (arbitraria
o meno). Le caratteristiche "operative" dei due tipi sono ESATTAMENTE
le stesse.

Non esiste un tipo Currency in Java?
Sì, si chiama BigDecimal.
(La classe java.util.Currency non rappresenta il numero).

almeno 8 decimali e, mi sono sbagliato, 10 intere non credo piu' bastino.
Il cliente č interessato alle prestazioni ed č fissato con Java? Mi
sembra una politica un po' ottusa. Se č cosě interessato alle
prestazioni, le prestazioni dovrebbero essere la sua prima
preoccupazione e quindi il linguaggio adoperato per raggiungerle una
scelta - diciamo - secondaria. Se devi arrabattarti per trovare una
soluzione restando nel recinto di Java, non credo arriverai a far
molto meglio di quanto realizzato col BigDecimal. L'unica via, a mio
avviso, č riscrivere il nucleo di calcolo in C++.


Infatti il BigDecimal è un intero. Quando dicevo intero non intendevo 
'Integer' o 'int' intendevo intero. Forse dovevo usare un'altra parola, 
non so.



Capito. Mi avete insegnato una cosa nuova.
Forse Currency era il nome del tipo da usare in Visual Basic 6, per 
quello ho fatto confusione.


 scelta - diciamo - secondaria. 
Magari ha altri motivi per richiedere che il lavoro sia fatto in Java.
Spesso i requisiti del sistema spesso sono in contraddizione tra di 
loro, è compito degli sviluppatori negoziarli con il cliente in modo da 
trovare una configurazione fattibile e accettabile.
In questo caso c'era un requisito di tipo vincolo: "usare java" e un 
requisito di tipo prestazionale : "tot di operazioni al secondo".
La negoziazione dei requisiti in contraddizione dovrebbe essere fatta 
nelle prime fasi dello sviluppo.
In genere va bene dire di sì al cliente, pero' se quando ti chiede una 
cosa impossibile gli rispondi "sì va bene!" senza assicurarti di poterla 
fare poi rischi di andare in contro a problemi tipo questo.


non so.
Mi era sembrato di capire che proponessi il BigInteger come
alternativa al BigDecimal.

quello ho fatto confusione.
Credo di sě. Anche in Delphi si chiama Currency.

fare poi rischi di andare in contro a problemi tipo questo.
Concordo al 100%.


Avevo nominato BigInteger perché l'OP aveva chiesto se qualcuno 
conosceva un'alternativa al BigDecimal, non perché sapessi o pensassi 
che per il problema in oggetto fosse una scelta ottimale.
L'affermazione sugli interi che possono rappresentare in fixed point la 
intendevo slegata.
Io quello che farei al posto dell'OP e determinare prima di tutto i bit 
richiesti per rappresentare tutti i possibili valori e poi decidere in 
base ai requisiti di prestazioni come implementarlo.


 a questo punto io penserei a qualcosa diverso da java.
ovviamente +1, ma con tutto un marchingegno da riscrivere...
-- 
-riko

 Sono cose diverse.
Ovviamente so che sono cose diverse, in realta' dobbiamo limitare entrambe 
le cose.
Tommy 

 a questo punto io penserei a qualcosa diverso da java.
non si puo'... sigh!


Capisco la memoria utilizzata, ma perché anche il numero di allocazioni?


 migliorare nel modo di gestire il progetto.
Ragazzi, davvero non mi interessa parlare di questo...
non ho mai detto che le specifiche si possono cambiare in modo non gestito, 
il cliente vuole prestazioni e il cliente e' probabilmente disposto a 
"rilassare" alcune specifiche per ottenere maggiori prestazioni, e gia' lo 
ha fatto un paio di volte. Siamo in continuo contatto con il cliente.
Tommy

"Andrea Laforgia" <a.laf...@andrealaforgia.it.invalid> wrote


Gia' il cliente e' un cliente grosso che ha pressioni ed accordi con varie 
ditte e spesso vuole cose non coerenti. La politica e' certamente non delle 
migliori, ma questo non mi riguarda, ho gia' consigliato piu' volte di 
scrivere alcune parti del sistema in C++.
Quindi in sostanza concordo, ma siamo bloccati nel recinto Java...
Tommy 

 Ragazzi, davvero non mi interessa parlare di questo...
Non devi parlarne per forza, il thread puoi averlo iniziato tu ma le 
discussioni che ne scaturiscono non sono e non devono essere sotto il 
tuo controllo. Si discute per discutere non per trovarti una soluzione.


 controllo. Si discute per discutere non per trovarti una soluzione.
Tranquillo, se anche volessi non posso controllare il thread. Siete 
liberissimi di parlare di queste cose anche all'infinito. Ad ogni modo io ho 
precisato pero' che *IO* non sono iteressato piu' di tanto a dare 
spiegazioni/motivazioni in quanto non mi occupo di requirements, di project 
management, etc...
Ad ogni modo non mi pareva il caso di dover fare questa 
precisazione...alquanto scontata. 

 
Versione JVM?

cicap ha scritto:

Altra proposta: riesci a riprodurre il problema con un piccolo banchmark 
che fa piu' o meno le operazioni che state facendo voi nel programma?

Capisco la memoria utilizzata, ma perché anche il numero di allocazioni?
Forse perché in un sistema con garbage collection, inevitabilmente, il
numero di allocazioni influenza sottilmente la memoria utilizzata. In
un linguaggio in cui c'è deallocazione deterministica (C, C++,
Delphi), si può mantenere una quantità fissa di memoria allocata anche
allocando e deallocando moltissime volte nell'unità di tempo. Ovvio
che le prestazioni generali del sistema peggiorano perché aumenta la
frammentazione della memoria, però il consumo effettivo di memoria non
cresce. Nel caso della GC si deve dare il tempo al "collector" di
raccogliere la "garbage".

 
ROFL...sì...decisamente è quello che si fa ultimamente in questo NG. 
Discutere per discutere...e senza nessuna utilità. Non che sia 
necessariamente un male, ma francamente penso che il trio Francia, 
Laforgia e Cara stia un po' esagerando. Boh...probabilmente hanno poco 
da fare in questi giorni...ma andare a pescare, no eh? :)
E' vero che un NG è fatto per discutere, ed è abbastanza normale che la 
discussione spesso prenda strade diverse dal post originale. Ed è 
soprattutto vero che non è un help-desk. Però trovo abbastanza 
scocciante che qualcuno pensi che sia normale di poter appropriarsi (e 
spesso) di un thread per discutere delle cose che più gli interessano, 
disinteressandosi invece dell'argomento che interessa a chi ha iniziato 
il thread...questo va sicuramente contro la netiquette.
Ad esempio, giusto per cercare di riportare la discussione in 
tema...nessuno che abbia provato ad ipotizzare che possano esistere 
delle implementazioni alternative a BigDecimal?
Io l'ho fatto, e ho trovato:
http://www2.hursley.ibm.com/decimalj/
(credo sia già incluso co JDK 5...ma non ho verificato)
http://jscience.org/
http://www.prosperosoftware.co.uk/software/java/decimals/numjbetter.html
Tommy...se hai modo di provarle, facci sapere se effettivamente qualcuna 
di queste risolve il tuo problema. Questo sì sarebbe interessante da 
sapere...invece che parlarsi solo addosso.
Ciao
   Lucio
-- 
Lucio Benfante
JUG Padova           
http://www.parancoe.org
 ...have a look at it!
www.jugpadova.it
 
http://www.jugevents.org

 questo va sicuramente contro la netiquette.
A me non sembra. Se magari porti il riferimento di un articolo di una 
netiquette che regola questi aspetti potrei ricredermi.


delle implementazioni alternative a BigDecimal?
Ovvio che non l'ho escluso, ma mi è sembrato di capire che la
questione sia piuttosto legata alla scelta iniziale: Java e il suo
ambiente, che per definizione non ha una gestione deterministica della
memoria allocata. Oltretutto non mi sembra che Java, in generale, e le
varie VM siano esempi brillanti di sistemi altamente performanti. E'
Tommy stesso a dire: "il cliente e' interessato alle prestazioni ed al
fatto che il software sia deterministico" (Tommy).
Se si vogliono comportamenti deterministici e un alto livello
prestazionale, forse conviene chiedersi se Java è lo strumento giusto.
Secondo me non lo è (e non deve offendersi nessuno per questo).
Come vedi, non ci si sta affatto parlando addosso. Prima di sputare
critiche, pensaci bene.

 il thread...questo va sicuramente contro la netiquette.
Sul fatto che le conversazioni sono pubbliche e non sono fatte solo per 
il bene dell'OP:
http://mindprod.com/jgloss/newsgroups.html#PUBLIC
I newsgroup sono fatti per permettere alla gente di discutere, per 
trasferire conoscenza tra le persone, non solo per risolvere i problemi 
di chi fa domande.


A me non sembra.
E infatti non lo è.

 da fare in questi giorni...ma andare a pescare, no eh? :)
Per favore non mi mettere in  mezzo. Mi posso sbagliare ma ho cercato 
sempre di essere in linea con l'OP (magari anche se era OT), tranne in 
"per chi e' in cerca di lavoro" ed anche qui, relativamente.
Sul post di Tommy non sono intervenuto. Mi sarebbe piaciuto chiedere: 
come quando e' perche' hanno deciso che i bigdecimal sono cosi' 
"massacranti". Avrei qualche "nanetto" da citare di come, spesso, si 
decide aprioristicamente dov'e' il problema senza valutare 
effettivamente se quello e' il "problema".
Tommy non ha detto nulla rispetto a cio'.Solo cicap ha fatto un 
tentativo di farselo dire.
Pescare mi annoia. Preferisco un buon "safari" fotografico a caccia di 
orchidee.
Se vuoi si potrebbe sempre discutere del significato di "utilita'" ;<)
Cosi da un trio diventa un quartetto. ari ;<)
-- 
ac
y-1=x

 sapere...invece che parlarsi solo addosso.
Grazie,  avevo gia' trovato questi links, ma riguardandoli ora, mi sa 
proprio che mettero' alla prova jscience, ci sono alcune cose che mi 
interessano... 

 di farselo dire.
Come: profiling, instrumenting, dtracing, debugging.
Quando: qualche settimana fa
Perche': perche' e' praticamente l'unica fonte (rimasta) di numerose 
allocazioni di memoria, utilizza una buona percentuale di CPU ed e' causa di 
basso determinismo del codice (che deve essere soft-realtime)
Tommy

 basso determinismo del codice (che deve essere soft-realtime)
Java per software real time!


 basso determinismo del codice (che deve essere soft-realtime)
Uhmmm.....questa me l'ero "immaginata", sempre da quello che hai 
scritto. Ho l'impressione, pero', che sia un "quasi" realtime.
Mi spiego e immagino. Ricevi qualche file a scadenza di tempo (diciamo 
ogni 30sec?), che devi elaborare? Che volumi? e se e' cosi' come lo fai?
Immagino che sia una applicazione "desk" h24 e che i sui dati siano poi 
fruibili da una applicazione web.
Una "esperienziaccia" in questo scenario l'ho fatta (in altro 
linguaggio) ed anch'io ho dovuto penare per stare nei tempi. Nel mio 
caso non avevo problemi di "bigdecimal" ma di calcolo ricorsivo si e di 
aggiornamento della base dati.
Non ho compreso pero' per quale motivo c'e' "basso" determinismo.
-- 
ac
y-1=x

 Java per software real time!
Non dovresti essere sorpreso visto che c'e' una versione apposta:
http://java.sun.com/javase/technologies/realtime/
se vuoi informazioni sul RTGC: 
http://java.sun.com/javase/technologies/realtime/reference/doc/release/JavaRTSGarbageCollection.html
Magari dai una occhiata... esistono threads che non vengono interrotti dal 
GC, questi si chiamano NHRT (non-heap realtime), questi devono usare solo 
primitivi (difficile) oppure riutilizzare oggetti pre-allocati in "Immortal 
Memory". Poi altri threads possono entrare uno "scope" quando lo abbandonano 
gli oggetti creati in quel scope verranno distrutti (sembra meglio di come 
e' in realta'). In fine il RT-GC e' "fully concurrent" (ma molto piu' lento 
e non generazionale). Poi il modello per le priorita' dei threads e' adatto 
a sistemi realtime.... etc...
In pratica a me non piace, fare le cose per bene diventa cosi' complesso che 
conviene davvero farle in C++! Ma ehi, il nostro cliente ha un accordo con 
Sun, sai per farsi pubblicita' a vicenda, e siamo costretti ad usare questa 
tecnologia.
Tommy

 Non ho compreso pero' per quale motivo c'e' "basso" determinismo.
No, non ricevo nessun file, sono tutte richieste fatte da utenti e il 
cliente deve garantire loro tempi di risposta e siccome e' in competizione 
con altri vuole tempi piu' bassi e piu' deterministici. Molto di piu' non 
posso dire, abbiamo un NDA molto chiaro in materia.
I tempi di determinismo ci sono in quanto si parla di alcune centinaia di 
microsecondi, questi sono i tempi ed il sistema tra le altre cose e' 
distribuito e quindi tra i tempi spesi sulla rete etc... in Java dobbiamo 
essere efficientissimi ed estremamente determnistici, i margini sono 
bassissimi. Un esempio banale, una struttura dati normale che quando diventa 
"piena" raddoppia e copia il contenuto puo' causare problemi, quindi ad 
esempio dobbiamo evitare strutture dati di questo tipo... Quindi stiamo 
rimpiazzando varie collection della JDK con quelle di javolution, ma per big 
decimal non abbiamo trovato alcuna alternativa per ora. Ora le priorita' 
sono cambiate e sto lavorando temporaneamente ad un altro problema, ma la 
prossima settimana dovro' decidere se implementiamo qualche cosa noi, 
teniamo bigdecimal, o passiamo ad una alternativa (l'unica seria trovata 
forse e' jscience, che tra le altre cose andrebbe benissimo in quanto usa 
javolution e quindi e' piu' deterministica, puo' riutilizzare memoria 
tramite pooling o scoped memory... ok sara' piu' lenta, ottimizzeremo 
altrove, bigdecimal e' troppo poco deterministica e mette a dura prova il 
nostro RTGC (e diventa difficile usare scoped memory con bigdecimal).
Sono ottimista per jscience, come ho detto, se anche fosse piu' lenta, 
ottimizzeremo altrove. Pero' francamente non ho ancora avuto molto tempo per 
guardarla/provarla, quindi per ora tengo solo le dita incrociate.
Grazie a tutti,
Tommy

 Versione JVM?
una vm speciale che implementa RTSJ.
Tommy

 che fa piu' o meno le operazioni che state facendo voi nel programma?
no, il problema non si verificherebbe su di una VM normale con un buon 
generational garbage collector. O meglio, in parte non potresti notare i 
problemi ed in parte non si verificherebbero.
Tommy

 a sistemi realtime.... etc...
Interessante, grazie del link.
Adesso capisco perché devi stare attento con le allocazioni.


 decimal non abbiamo trovato alcuna alternativa per ora.
in numeri quanto? soprattutto percentualizzati rispetto agli altri tempi?
Basta un pacchetto perso sull'ip per mangiarti tutto il tempo ed il 
determinismo che riesci ad ottenere. Tutto cio' a meno che non ci sia 
dall'altrea parte un "supercalcolatore" che riesce a spararti sulla 
linea qualche terabyte al secondo.
Mi  spiace ma con buona approssimazione il tuo, teoricamente 
interessante, per la prassi  mi sembra un "falso" problema.
Il consiglio e': comprate e fate comprare ai vs clienti un pezzo di 
ferro piu' potente, e' piu' economico e risolve alla radice la questione.
Magari usate anche jsp?
-- 
ac
y-1=x

 Magari usate anche jsp?
No, non e' un sistema web based.
Tommy


Qua credo di aver capito cosa intendeva il mio 'quasi omonimo' ;)
Il mio prof di Informatica2, all'università amava porre l'accento
sugli algoritmi, anzichè sui linguaggi di programmazione o sulle
ottimizzazioni.
Molte dimostrazioni matematiche, per farci vedere che un buon
algoritmo implementato in Bytecode java non compilato, che esegue un
linguaggio di scripting anch'esso interpretato (che so, ruby), che
emula magari un altro linguaggio di scripting (che so, LUA), strabatte
in performances un algoritmo implementato in ASM ma anche solo un po'
più complesso in termini asintotici.
Qui tu hai un problema di ottimizzazione, ovvero il software che
abbiamo fa quello che vuoi (parlo della classe BigDecimal), ma non nel
tempo che tu vuoi. Il punto è: sei sicuro di non poter ottimizzare
l'algoritmo di calcolo? Capisco il NDA, ma penso che almeno la
complessità O() dell'algoritmo tu ce la possa dire, non penso sia pure
quella segreta. Se lo fosse, probabilmente sigificherebbe che lavorate
con criteri di segretezza tali da non poter nemmeno parlare di
BigDecimal :D !
In soldoni, tutto questo per dire: sei sicuro che il problema sia la
classe BigDecimal? Non è che magari limando da qualche altra parte
riesci ad ottenere benefici anche maggiori?

 No, non e' un sistema web based.
Un client-server? message driven?
-- 
ac
y-1=x

 era meglio promettere tempi di risposta medi.... :)
vedi sopra



Tommy sembra abbastanza sicuro di questo.
In relazione alla "sicurezza". Al momento mi sembra di aver capito che 
e' una applicazione "Client-server" forse message driven. Non ho invece 
ancora capito quanti cicli "bigdecimal" fa all'interno di una unita' 
transazionale. Se fa sopra ai 10^4 cicli posso cominciare a capire che 
il problema puo' nascere ma con cicli inferiori ho il dubbio che il 
tempo dedicato a fare calcoli sia di un fattore 10-100 (mi tengo 
stretto)  inferiore al tempo totale della transazione.Se poi i calcoli 
che deve fare "possono" essere gli stessi per un fattore tempo, diciamo 
10 sec per stare bassi, non vedo perche' non sia possibile farli 
"asincronamente" in modo tale che gli utenti si limitino a pescare dal 
precalcolato o comunque usare dei "semilavorati" gia pronti.
Insomma un po' come lavorare a Lotti ;<)
-- 
ac
y-1=x

 complessità O() dell'algoritmo tu ce la possa dire,
nel caso normale puoi semplificare dicendo che e' costante (dove la costante 
k e' composta da piu' operazioni), nel caso peggiore e' lineare, ma il caso 
peggiore per quanto in teoria possible, in pratica non capitera' mai.
Tommy

 tutto. Non credo che gli strumenti standard siano sufficienti/adatti.
?!
Usiamo dtrace in modo particolare, poi abbiamo uno strumeto scritto in house 
che raccoglie statistiche sulla life-cycle di ogni transazione, poi usiamo 
jprofiler. dtrace ed il sistema in house sono quello che usiamo il 90% del 
tempo.
Tommy

 dal
Purtroppo non e' proprio possibile per la natura del sistema.
Tommy

 E' un modo dialettale di dire scherzavo? Di dove?
http://www.demauroparavia.it/20667

 Tommy
ciao Nicola
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 prestazioni ?
Mi sa che non puo' perché si tratta di un'applicazione finanziaria che 
richiede calcoli precisi. Cosa che l'aritmetica floating point non ti 
puo' dare.
-- 
Andrea Francia
http://www.andreafrancia.it/

 
http://www.demauroparavia.it/20667
Ok, a quanto pare ho seri problemi con l'italiano ;-)
Parola nuova... non si finisce mai di imparare...
Grazie,
Tommy

> JProbe o tool simili ?
si, non jprobe, ma dtrace e jprofiler in particolare.
Tommy

Alla fine come hai risolto?
-- 
Andrea Francia
http://andreafrancia.blogspot.com/2008/06/macross-frontier.html

 Alla fine come hai risolto?
Alla fine non abbiamo ancora risolto, le priorita' sono temporaneamente 
cambiate, ma presto dovro' ritornare a questo problema.