Newsgroup: it.comp.java
Titolo: Re: Alcuni programmi java sprecano troppa CPU!

 evitare questo genere di problemi?
programmare decentemente.
-- 
Davide Consonni
http://csvtosql.sourceforge.net

 questo genere di problemi? 
Ovviamente ci sono una serie di tecniche di programmazione che se 
applicate permettono di evitare di avere problemi di performance 
superflui, pero' non è certo un argomento da post in un newsgroup.
Andrea

 boh mi sembra strano.
"s = s + x" e "s += x" sono esattamente la stessa cosa, nessuna
differenza (se non nella leggibilità del codice).
Inoltre s = s + x viene tradotto dal compilatore in:
s = (new StringBuffer(s)).append(x).tostring();
Questo significa che viene creato un nuovo stringbuffer e ci viene
fatto l'append della tua stringa.
A sua volta questo implica effettuare una copia della stringa in una
nuova area di memoria.
Ad esempio:
String x = "c";
String s = "";
for(int i=0; i<1000; i++) {
  s += x;
}
Questo causa la copia della stringa s e della stringa x 1000 volte.
Tenuto conto che ad ogni ciclo la stringa s aumenta di dimensione questo
significa copiare circa
1 + 2 + 3 + 4 + .... + 1000 = 500*500 = 250000 caratteri. [(n/2)^2]
Piu' i 1000 totali dell'append di t.
Uno stringbuffer invece (che se non ricordo male avrebbe raddoppiato
la propria dimensione ogni volta che necessario) avrebbe fatto:
1 + 2 + 4 + ... + 512 = 1023 caratteri [2*n - 1]
Sempre piu' i 1000 caratteri di t.
Una bella differenza!
Il codice sarebbe stato: 
String x = "c";
StringBuffer buff = new StringBuffer();
for(int i=0; i<1000; i++) {
  buff.append(t)
}
s = buff.toString();
Andrea
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG


A proposito di ciň...secondo voi é vero che java non é piu' lento di un 
eseguibile nativo?
Ho sentito dire questo qualche tempo fa, perň non mi spiego perchč ad 
esempio prodotti come NetBeans sicuramente ben programmati, siano un pň 
troppo lentini, in caricamento soprattutto, ma anche tal volta in 
esecuzione, rispetto ai tool che uso sotto windows (non scritti in java).

 e che implicano un impiego elevato di CPU ?
Per mia esperienza sono algoritmi che popolano / scandagliano alberi (o
comunque strutture più o meno reticolari) poco ottimizzati.
Istanziare oggetti "a casaccio" è anche molto dispendioso, è forse una
delle operazioni più costose in assoluto, (escluso quel succhiarisorse del
garbage collector...) per cui suggerisco sempre di istanziare oggetti
locali ai metodi con parsimonia.
Alex.
-- 
___________________________________________________________
a p bertolini
(Tribù Digitale Blackmambo: 
www.blackmambo.it
)

 implicano un impiego elevato di CPU ?
Un errore che ho visto fare da parte di molti principianti (e che ho fatto
anch'io all'inizio) è il leggere da un InputStream usando come condizione di
partenza una scansione continua (ciclo while o simili) sul metodo
available(). Garantito un piantaggio dell'applicazione quasi istantaneo.
Il metodo più corretto in questo caso è:
- leggere un byte dall'InputStream con una chiamata bloccante a read()
- uscito da read(), chiamare *una* volta available() per sapere se vi è
altro da leggere
- leggere i restanti byte che sono rimasti "in canna" con una chiamata a
read(byte[] b, int off, int len) assicurandosi di passare in "len" la
grandezza ricavata da available()
- controllare un'eventuale condizione di uscita
- se la condizione di uscita non è verificata, ricominciare il ciclo.
Il metodo read() è bloccante, ma se un'altro thread chiama close() sullo
stesso InputStreamm, la read() si sblocca lanciando una IOException.
-- 
Fermiamo Scientology prima che sia troppo tardi!!!
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx/
(per rispondere personalmente leva IlDitoDalCulo)

 boh mi sembra strano.
scrivendo s+=x ponendo che s e x siano due String è come scrivere s= new
String(s+x), ovvero ogni volta vieni istanziato un nuovo oggetto di tipo
String, mentre usando StringBuffer.append() non viene istanziato un nuovo
oggetto StringBuffer ma modificato quello esistente, sprecando meno memoria.
-- 
Dimux
http://www.128byte.com
Scopri gli errori e i segreti dei tuoi film, album e programmi
preferiti!

 Andrea
Interessante l'esempio sullo Stringbuffer...ma non ho afferrato bene il 
concetto riguardo all'InputStream...in alcuni casi non è preferibile 
usare uno InputStream + BufferedReader...e svuotare il buffer al suo 
riempimento (o precocemente da codice) per fare un minor numero di letture!?
Comunque non ho ben afferrato lo spreco che avviene con 
l'InputStream...! :-)
Grazie in anticipo per la delucidazione,
jRed
PS: Non è che ci lavoro da molto con gli stream...spero di non aver 
detto infamie! :-D

 l'InputStream...! :-)
Non č tanto l'inputStream quanto l'errore di usare un ciclo while per fare
del "polling". Vale per InputStream come vale su tante altre risorse.
Cmq usare il BufferedReader č sicuramente meglio visto che le sue
operazioni di read sono meno dispendiose dell'equivalente per InputStream
Alex.
-- 
___________________________________________________________
a p bertolini
(Tribů Digitale Blackmambo: 
www.blackmambo.it
)

 operazioni di read sono meno dispendiose dell'equivalente per InputStream
Bene, ho capito, invece possono essere risponsabile di un eventuale calo 
di prestazioni un eccessivo uso di assertion oppure no?! Non mi ricordo 
dove avevo sentito una cosa simile...potrei anche sbagliarmi con un 
eccessivo uso dei thread!
jRed

 dove avevo sentito una cosa simile...
Se le espressioni da te usate nelle assertion sono complesse (leggi: 
lunghe da calcolare) e vengono testate continuamente in effetti può 
essere un problema.
Puoi verificare eseguendo il tuo programma con le assertion disabilitate 
(e' un parametro della virtual machine, ma non ricordo quale).
Se le prestazioni aumentano hai individuato un problema.
Andrea

 Se le prestazioni aumentano hai individuato un problema.
Il parametro l'ho trovato è il -da (disable assertion) ma di base sono 
già disabilitate e per attivarle dovevo fare il -ea (oppure -source 1.4)...
Grazie ancora,
jRed


Giusto, ricordavo male. Comunque se normalmente esegui con le assert 
disabilitate non dovresti avere problemi di prestazioni (a meno che non 
ne hai messe tante, ma veramente tante).
Andrea

 wrote:

Questa e' una questione un po' spinosa, in rete trovi bench che
confermano e al contempo smentiscono questa idea.
In linea di massima, le nuove VM hanno fatto passi da gigante e tra JIT
e ottimizzazioni varie non hanno molti problemi ad eseguire calcoli
anche molto complessi. E' infatti sulle operazioni di calcolo che Java
se non uguale e' comunque molto vicino al codice nativo come velocita'.
Il problema *enorme* per quanto riguarda la velocita' e' l'uso delle
interfacce grafiche. SWING per mantenere combatibilita' varie e'
veramente lentissimo. Questo fa si che l'utente percepisce come lenta
tutta l'applicazione mentre sotto non e' per nulla lenta.
-- 
Ciao
Fabio