Newsgroup: it.comp.lang.visual-basic
Titolo: Ottimizzazione codice (speed improvement)

E' un'operazione che faccio spesso, prima del rilascio di una nuova release 
di un software.
Capita sempre che, a seguito di modifiche e/o aggiornamenti del software, 
alcune routine diventino "inadeguate" (o per meglio dire, non più 
ottimizzate).
Capita anche spesso che per risolvere in fretta i problemi, si aggiunga del 
codice che non rispetta il criterio iniziale di ottimizzazione del flusso 
della procedura.
La classica "patch"... :-)
Ma il programma va bene... l'utente è contento... però nella tua coscienza 
lo sai, che se avessi scritto tutto oggi lo avresti fatto diversamente.
E così ogni tanto rimetto mano al codice, ottimizzando qua e là, eliminando 
instruzioni ridondanti, o riscrivendo delle funzioni più ottimizzate 
rispetto alle precedenti.
Ad esempio, oggi il problema che vorrei risolvere è questo:
Ho un certo numero di records, in un database, contenenti data, ora, e testo 
di alcuni messaggi ricevuti ed inviati (il log di una chat, per intenderci).
Per visualizzare l'intera chat di un utente in un box RTF, eseguo 
nell'ordine:
- Dim X$, Y$ as String
- (query sql)
- (loop di lettura del recordset)
  - lettura del testo nella variabile di lavoro Y$
  - aggiunta di informazioni iniziali (nome, data) alla variabile Y$
  - aggiunta del cr/lf finale alla variabile Y$
  - ulteriori formattazioni (colore, grassetto...)
  - accodamento della variabile Y$ alla variabile X$  (X$ = X$ & Y$)
- end loop
Infine
- RichTextBox.TetxRTF = X$
mi permette di effettuare l'output formattato di tutta la chat in un, box 
RTF.
Eseguo questo ciclo perché ho bisogno di formattare i testi dei messaggi, 
con colori e grassetti, al fine di ottenere un risultato estetico e ben 
leggibile nel risultato finale.
Funziona tutto bene... magnificamente... se non fosse che ormai le chat 
iniziano a diventare enormi (migliaia di records), e la routine di cui sopra 
sta iniziando a diventare troppo lenta.
Anche tre o quattro secondi, per visualizzare un'intera chat!
Troppo!!!!!  :-(
Ho analizzato la routine, con dei timer molto precisi, ed ho scoperto che il 
collo di bottiglia si trova UNICAMENTE in una singola istruzione:
l'accodamento dei singoli testi nella variabile finale X$   (X$ = X$ & Y$)
Io credo che Visual Basic operi una sorta di ridimensionamento di memoria, o 
di riallocazione interna dello spazio riservato alle variabili, ogni volta 
che riassegno il valore della variabile X$. E penso che questo 
ridimensionamento generi il mostruoso rallentamento che riscontro nella 
routine di cui sopra.
Secondo voi, è possibile con Visual Basic definire una matrice di stringhe, 
e rileggerla in una "botta sola" assegnandole un nome alias diverso??
Mi spiego meglio:
Dim Y$(1000) as String
X$ = tutto l'array Y$( )
Come faccio a definire X$ in questo modo?!?
Praticamente sarebbe come il pointer* del linguaggio C, a me serve il 
puntatore al primo elemento della matrice, e la lunghezza totale di tutti 
gli elementi... è possibile farlo, con Visual Basic?
Se fosse possibile, eviterei l'accodamento continuo delle singole Y$ nella 
variabile finale (X$ = X$ & Y$), evitando in questo modo quel fastidioso 
rallentamento... :-((
Grazie a tutti per i vostri suggerimenti, come avrete capito non sono molto 
esperto di Visual Basic, però sono sempre ben disposto ad imparare tecniche 
nuove (e più efficienti) per ottenere buoni risultati.
Lo so.... avrei dovuto scriverlo in C, porc... :-))
Saluti
B.

 l'accodamento dei singoli testi nella variabile finale X$   (X$ = X$ & Y$)
Prova questo, vedrai che differenza...
   Dim X As String
   Dim Substr As String
   Dim Ind As Long
   Dim Length As Long
   Dim i As Long
   X = Space(1000000)
   Ind = 1
   For i = 1 To 10000
      Substr = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      Length = Len(Substr)
      Mid$(X, Ind, Length) = Substr
      Ind = Ind + Length
   Next i
Per la cronaca, non è farina del mio sacco, ma di Balena (I trucchi di VB).
Ciao, Paolo


prova a fare cosi' non ti garantisco che i risultati siano buoni
0) calcola la lunghezza totale del testo diciamola LL
1) prepara con string() una stringa di dimensione sufficiente a 
contenere tutto il testo
x$ = string(LL," ")
2) inserisci in x$ le varie sotto stringhe con
mid(x$,???,len(Y$(i)) = Y$(i)
al posto di ??? ci va la posizione giusta in cui inserire il testo
forse, FORSE, ti eviti la riallocazione della stringa x$ ad ogni iterazione.
altrimenti ti tocca andare di copymemory ( si chiama cosi' l'API ? nno 
ricordo )

 - Dim X$, Y$ as String
Mi scrive l'esatta dichiarazione delle due stringhe, precisa precisa
come ce l'hai nel sorgente?

 - RichTextBox.TetxRTF = X$
Fai questo, dovrebbe essere più veloce:
    RichTextBox.SelRTF = Y$
end loop
Bye
Raf
-----------------------------------------------------
Funk: cooler than the other side of the pillow.

 VB).
Sì, vabbeh, io già la usavo quando Balena non si sapeva nemmeno chi fosse.
'Sto Balena è un po' troppo sovrastimato secondo me: sicuramente in gamba, 
ma non si può sempre attribuirgli il merito per qualsiasi boiata che 
riguarda VB (sembra che l'abbia scritto lui)!
Ciao 

 qualsiasi boiata che riguarda VB (sembra che l'abbia scritto lui)!
ROTFL & quoto.
Era un'ottimizzazione che lessi già in un libricino allegato a una qualche
rivista inglese ai tempi del VB 1.0, o forse del VB 2.0 "Primer Edition".
Comunque ne parlammo anche sul NG, e se non ricordo male il risultato
più veloce di tutti era con la CopyMemory.
D'altra parte una guglata per "fast string vb" dà risultati interessanti...
Per esempio, il sito Aivosto:
http://www.aivosto.com/vbtips/stringopt.html
 e tutti i link seguenti,
oppure:
http://www.freevbcode.com/ShowCode.asp?ID=4165
 (CopyMemory)
oppure.... ;-)
Bye, G. 

 rivista inglese ai tempi del VB 1.0, o forse del VB 2.0 "Primer Edition".
Non so, io la scoprii su VB5 (il primo VB che usai intensamente) per mio 
conto (eeeh... pei tempi passati, quando ancora si aveva il tempo di 
sperimentare tutto lo sperimentabile :) )
Ciao

Un unico post per ringraziarvi tutti, sia per gli ottimi consigli che per i 
FANTASTICI link che avete inserito in questo thread.
Specialmente il primo (Aivosto) è davvero mooolto interessante... da leggere 
con molta calma, e da assimilare come "modus programmandi"!!
;-)
Nei prossimi giorni farò dei test specifici, sulla routine di 
visualizzazione della chat di cui sopra, e se vi fa piacere posterò i 
risultati comparativi tra le varie soluzioni prospettate (Mid$, CopyMemory, 
ecc...).
Grazie ancora a tutti
B.