Newsgroup: it.comp.java
Titolo: Velocita' ridicola

Dovendo io scrivere un file, utilizzo una stringa, alla quale, 
all'interno di un for, concateno delle sottostringhe con il classico 
comando stringa += sottostringa;
Ora: se la stringa diventa particolarmente grossa (ma nemmeno troppo, si 
parla di un centinaio di kappa), la concatenazione diventa molto lenta, 
al punto che la jvm si ciuccia per un minuto buono il 100% della cpu 
prima di risvegliarmi il sistema.
Tutto cio' e' ovviamente inacettabile.
Idee?

 Idee?
Prima di tutto utilizzare lo StringBuffer (meglio StringBuilder se JDK 
 >= 1.5). Stai sprecando un bel po' di oggetti col metodo stringa += 
sottostringa.
Secondariamente il problema potrebbe anche essere dovuto al modo in cui 
stai scrivendo sul file. Ma senza vedere il codice...
pole
-- 
ammentos - a lightweight persistence framework for JDK5
http://www.sourceforge.net/projects/ammentos
http://ammentos.biobytes.it

 stai scrivendo sul file. Ma senza vedere il codice...
Presto detto:
Premessa: ho un po' migliorato le cose usando una stringa temporanea per 
le varie concatenazoni.
Va decisamente meglio, ma rimangono sempre quei 2/3 secondi di freeze 
totale che vorrei togliere.
filecont contiene il contenuto del file, un file di testo con le 
informazioni in formato wavefront di un oggetto 3d.
Le informazioni son contenute dentro ad una serie di Vector (v,vt,vn,f), 
per ciascuno di essi eseguo un for, ne tiro fuori i dati e li concateno 
al file.
public void save(String filename) throws IOException {
         String filecont = "# generato da PdG\n\n";
         if (this.mtllib != null)
             filecont += "mtllib "+this.mtllib+"\n\n";
         String temp="";
         if (this.v != null) {
             for (int i=0;i<this.v.size();i++) {
                 Vector3d point = (Vector3d) this.v.get(i);
                 temp+= "v "+point.x+" "+point.y+" "+point.z+"\n";
             }
             filecont += temp+"# "+v.size()+" vertici\n\n";
         }
         temp="";
         if (this.vt != null) {
             for (int i=0;i<this.vt.size();i++) {
                 Vector2d point = (Vector2d) this.vt.get(i);
                 temp+= "vt "+point.x+" "+point.y+"\n";
             }
             filecont += temp+"# "+vt.size()+" coordinate texture\n\n";
         }
         temp="";
         if (
this.vn
 != null) {
             for (int i=0;i<this.vn.size();i++) {
                 Vector3d point = (Vector3d) this.vn.get(i);
                 temp+= "vn "+point.x+" "+point.y+" "+point.z+"\n";
             }
             filecont += temp+"# "+vn.size()+" vettori normali\n\n";
         }
         if (this.s != null)
             filecont += "s "+this.s+"\n\n";
         if (this.usemtl != null)
             filecont += "usemtl "+this.usemtl+"\n\n";
         temp="";
         if (this.f != null) {
             for (int i=0;i<this.f.size();i++) {
                 Face face = (Face) this.f.get(i);
                 temp+= "f "+face.toString()+"\n";
             }
             filecont += temp+"# "+f.size()+" facce\n";
         }
         FileUtilities.saveFile(filename+".obj",filecont);
     }

 Idee?
E' una cosa arcinota fin dalla versione 1.0 di Java.
Non ricordo bene la motivazione.
Comuinque la soluzione e' usare
lsb StringBuffer = new StringBuffer( stringaIniziale);
oppure anche uno SB vuoto
poi
lsb.append( tuaStringa)
alla fine con un
lsb.toString hai la stringa
Io uso sempre il += per casi semplici per comodota' perche mi rompo con lo
sb
pero' in casi un pochino pesanti come il tuo uso lo stringbuffer
dovrebbe fare al caso tuo
ciao Nicola
 
 
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 totale che vorrei togliere.
Hai provato a fare un po' di debugging o a mettere del logging per 
capire quale sia il punto responsabile del freeze?
BTW la stringa temporanea non è che cambi di molto la sostanza delle 
cose. Hai semplicemente spezzato in tre tronconi la costruzione del 
testo finale, ma poi in ognuno dei tre continui a lavorare a colpi di +=.
Con lo StringBuilder/Buffer basterebbe un unico buffer su cui via via 
fare l'append delle varie parti, decisamente più efficiente.
Cmq niente di strano che il freeze possa anche essere dalle parti di 
FileUtilities.saveFile().


 Tutto cio' e' ovviamente inacettabile.
E' vero, è inaccettabile sottoporre il Garbage Collector a tutto questo
lavoro! Ogni stringa che crei inavvertitamente con la concatenazione
spreca risorse e poi deve essere collezionata dal GC, inutilmente. Le
stringhe sono oggetti immutabili, devi usare uno StringBugger o uno
StringBuilder se non vuoi sprecare risorse ed avere un unico buffer. 
uL
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 FileUtilities.saveFile().
Oddio, dubito..
Comunque eccolo
   public static final void saveFile( String fullname,String cont) 
throws IOException {
         // apre il file
         java.io.File fileout=new java.io.File(fullname);
         byte[] line=cont.getBytes();
         java.io.FileOutputStream out = new 
java.io.FileOutputStream(fullname);
         out.write(line);
         out.close();
     }

      }
se vuoi ottimizzarlo usa un BufferedOutputStream attorno al
FileOutputStream.
ciao

 fare l'append delle varie parti, decisamente più efficiente.
Fatto.
Ora va che e' una scheggia.
Grazie

 Idee?
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StringBuffer.html
-- 
Giambo - Occhio al filtro antispam _e_ alla whitelist !