Newsgroup: it.comp.lang.visual-basic
Titolo: Come velocizzare questa procedura

Dunque, ho una procedura come quella in basso dove le variabili sono
Stringa: contiene tutti il testo letto da un file
Posarrivo: è la posizione fino al quale ho letto
Testospam(i): matrice String nella quale memorizzo i messaggi.
In pratica ho un file in cui le email sono accodate
e le separa un "From - Mon" (ho scelto questa cosa perchè non da tutte 
si riesce a ricavare l'ID o il boundary del messaggio).
Quindi per dividere questo file unico in vari files con le singole mail 
uso la procedura qui sotto.
     Do While PosArrivo < Len(Stringa)
         ReDim Preserve TestoSpam(i)
         TestoSpam(i) = Mid$(Stringa, PosArrivo, 10)
         PosArrivo = PosArrivo + 10
         Do While Mid$(Stringa, PosArrivo, 10) <> "From - Mon" And 
PosArrivo < Len(Stringa)
             TestoSpam(i) = TestoSpam(i) + Mid$(Stringa, PosArrivo, 1)
             PosArrivo = PosArrivo + 1
         Loop
         i = i + 1
     Loop
Il problema è che su un P4 2.0Ghz con Win2k SP4 mi va lenta come un mulo 
(30 sec circa)... E questo per sole 15-20 email! Ma se l'utente ha 
decine di email che cavolo succede? Soprattutto tenendo conto che viene 
richiamata ogni minuto circa.
Ecco dunque la necessità di velocizzare la procedura. Voi che mi 
consigliate?
bye
-- 
Gestione Ottica - Gestionale per Ottici e Programmi Gratuiti su:
http://www.nicolaottomano.it
Sinapsi Antispam. Antispam Gratuito.
http://www.sinapsi-antispam.tk
http://www.nicolaottomano.it/sinapsi.htm
Ingrosso Orologi.
http://www.supertop.it
email spamtrap: 
spam...@nicolaottomano.it

 (30 sec circa)...
Il problema secondo me è che se avanzi di 10 caratteri alla volta non puoi
essere sicuro di imbroccare la stringa.
Ma questo lo avrai considerato ;)
Perchè semplicemente non ti leggi tutto in blocco e non splitti con "From -
Mon" come separatore?
Ciao
--
Reporting tool: 
http://www.neodatatype.net
Qualunque mentecatto può scrivere codice che un computer possa capire.
I buoni programmatori scrivono codice che gli uomini possano capire.
[Martin Fowler]

 uso la procedura qui sotto.
[SNIP]
Ad una primissima occhiata:
Limita i Redim Preserve, invece di eseguirli ad ogni iterazione, dimensiona 
l'array a blocchi (100 o 1000 elementi alla volta, dipende dall'ordine di 
grandezza che ti aspetti); al termine fai un ultimo redim preserve per 
"trimmare" gli elementi superflui.
Sempre per lo stesso criterio, limita le concatenazioni di stringa
(TestoSpam(i) = TestoSpam(i) + ...)
e lavora anche qui con spazio predimensionato... dopo il primo 'Do While' 
alloca subito una stringa di un numero X di spazi (anche qui sai tu 
grossomodo lo spazio medio richiesto) e aggiungi un blocco solo quando hai 
esaurito lo spazio; per concatenare la stringa in coda al posto di '+' 
userai quindi Mid, in questo intendo l'istruzione, non la funzione:
Mid(TestoSpam(i), <il punto della stringa in cui sei>, 1) = Mid$(Stringa, 
PosArrivo, 1)
Vedi un po' che ne esce fuori,
Ciao
-- 
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown 

 Mon" come separatore?
Minchia! Ci credi che la Split non l'avevo minimamente presa in
considerazione?
Unico problema sarà che devo assegnare il tutto ad un Variant.
Ora provo e ti dico
Grazie


 PosArrivo, 1)
Questo fatto di allocare prima e ridimensionare dopo non mi dispiace, ma 
  come ti ho detto prima, non so a priori nè la quantità di msg ne la 
dimensione (tantopiù se vi sono allegati). Quindi la preallocazione la 
escluderei.
La risposta di Zanna mi sembra che aderisca meglio alle mie esigenze.
Grazie mille per l'aiuto



Reindosso il berretto dell'ottimizzatore... :)))
Allora, vediamo un po'.... Intanto, ti suggerisco di lavorare sugli
array di byte invece che sulle stringhe, sfruttando le potenzialitŕ di
CopyMemory e del passaggio delle stringhe ByVal (o era ByRef?); poi,
invece di lavorare con quel ReDim Preserve, che magna risorse come
pochi, potresti lavorare con un insieme di indici puntatori, per poi
usare in modo opportuno il solito CopyMemory; Infine, scorrendo
l'array di byte caricato, potresti fare una specie di Short Circuit
Evaluation (nel senso, un confronto su singolo byte č un fulmine, e se
un certo byte non vale Asc("F") č anche inutile considerare quanto
segue; Infine, usa meno chiamate a funzione possibile (ossia, non
usare ASC, ma impiega costanti.
Ultima cosa: invece di considerare una singola stringa per volta,
pensa a un buffer di lettura di almeno un 10/15 Kb.
Non ho tempo di buttare giů qualcosa, ma son sicuro che non ne hai
bisogno (e se ne hai bisogno, fammelo sapere che te lo butto giu' nei
prossimi giorni).
--
Ciao!
Luca Menegotto

 
Non so in che percentuale possa aiutare ma leggi qui:
http://vbaccelerator.com/home/VB/Code/Techniques/StringBuilder/article.asp
ciao
	maxx

 escluderei.
Anche in questo caso non intendevo un'unica preallocazione risolutiva, ma 
tante allocazioni a blocchi, mediamente grandi, da fare fintanto che ti 
serve spazio... stessi concetto di buffer di cui parlano Luca e l'articolo 
di emmex


Grazie a  tutti per i consigli.
L'idea del buffer non è male. Inoltre il confronto su singolo byte 
potrebbe essere vantaggioso sotto certi punti di vista, ma potrebbe 
generare casini in un messaggio email che contiene molte "F". Però con 
un pò di accortezza lo potrei implementare.
Anche l'idea di Luca Dormio di preallocare l'array e continuare poi con 
vari Redim a blocchi non mi dispiace (ottimizzerei anche se di poco).
Debuggando ho notato che ciò che mangia il 99% del tempo è il ciclo
         Do While Mid$(Stringa, PosArrivo, 10) <> "From - Mon" And 
PosArrivo < Len(Stringa)
             TestoSpam(i) = TestoSpam(i) + Mid$(Stringa, PosArrivo, 1)
             PosArrivo = PosArrivo + 1
         Loop
Quindi è su questo che devo lavorare maggiormente.
In questo senso la soluzione di splittare il file con la Split potrebbe 
essere molto veloce.
Ora mi metto al lavoro e vedo cosa può fare meglio all caso mio.
Grazie ancora.


 Grazie ancora.
Ciao
Raf

 esattamente la stessa cosa?
Mi era più consona la instrrev (inizialmente l'algoritmo era pensato per
trovare il boundary dell'email), ma non velocizzavo poi tanto.
La Instr non l'ho provata perchè preferivo partire dalla fine del file
(proprio per trovare il boundary).
Ora con la Split ho risolto e la routine va che è un missile (con 100
messaggi il tempo richiesto in elaborazione è impercettibile).
