Newsgroup: it.comp.lang.visual-basic
Titolo: Ciclo lento

Ho un programma che fa un ciclo tipo 1<->64000
Vi dico che sul mio PC (850mhz 320mb ram WinXP) impiega "solo" 3 minuti,
mentre sul PC di un mio amico (200mhz Win98 128mb ram) ben 8 minuti!!
Non c'č modo di velocizzarlo?
Fa solo un confronto tra due stringhe e aggiorna una progressbar
(indispensabile per cose cosě lunghe).
Quindi ho dovuto metterci un doevents.
Io carico un dizionario da file in un array di 64000 voci circa, quindi con
un ciclo for 0 to ubound(array) controllo se la parola va bene per me
Avete un'idea di come fare questo programmino + veloce?
Non ditemi fallo in C++ perchč non ho voglia/tempo di mettermi a smanettare
C++ per un programmino del genere.
Grazie
Ciao
Bald0z

 Non ditemi fallo in C++ perchè non ho voglia/tempo di mettermi a


> Posta il codice che ne diamo un'occhiata
Dizionario è un array in cui carico i termini da un file txt (circa 64000
termini)
    For Parola = 0 To UBound(Dizionario)
      DoEvents
      If Interrompi Then Exit For
      ProgressBar.Value = Parola
      'LCase -> Converte in minuscole
      If Right(Dizionario(Parola), Lettere) = LCase(Right(txtRima, Lettere))
Then
        lstRisultato.AddItem Dizionario(Parola)
      End If
    Next
E' uno stupido programmino per trovare delle rime........ Secondo me il
problema è che il ciclo di 64000 mette in crisi il VB...
provando a fargli fare il ciclo senza istruzioni cambia ben poco....
quindi....
Ciao
Bald0z

 quindi....
64.000 e' un numero basso, in compenso le tue prove sono incredibilmente
lente!
ho il sospetto che tu abbia qualche altro problema altrove... ho provato il
tuo codice sul PC piu' lento (PII 233 + 128 Mb) e impiega circa 40 secondi
con 2500 inserimenti il lista.
Si puo' ottimizzare almeno in 2 punti:
- il DoEvents ad ogni iterazione e' pesante, prova a farlo solo ogni n; ad
esempio aggiungendo
'DoEvents ogni 100 iterazioni
If Parola Mod 100 = 0 Then DoEvents
si passa da 40 sec. a 34 sec. circa, ogni 250 iterazioni arrivo a 32 sec.
- Gli aggiornamenti del ListBox, se le parole aggiunte sono molte, sono
pesanti; rendendo invisibile la lista prima del ciclo e visualizzandola
subito dopo si "limano" un'altro paio di secondi
tutto questo pero', per quanto utile, passa un po' in secondo piano rispetto
al fatto che non e' possibile che il tuo 850 ci metta quasi 5 volte di
piu'... addirittura dici che il ciclo senza istruzioni e' quasi uguale,
mentre se io eseguo
For Parola = 0 To UBound(Dizionario)
  DoEvents
Next
arrivo al massimo a 2 secondi! quindi ribadisco che, secondo me, c'e'
qualcos' altro che non va...
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 writes:
B>     For Parola = 0 To UBound(Dizionario)
B>       DoEvents
B>       If Interrompi Then Exit For
B>       ProgressBar.Value = Parola
B>       'LCase -> Converte in minuscole
B>       If Right(Dizionario(Parola), Lettere) = LCase(Right(txtRima, Lettere))
B> Then
B>         lstRisultato.AddItem Dizionario(Parola)
B>       End If
B>     Next
Beh, tanto per cominciare fai una volta sola il lavoro che puoi fare
una volta sola 
	buf = LCase(Right(txtRima,Lettere))
e a  definire Parola come Long. Poi  se riesci a mettere  tutto in una
tabella di un DB SQL potresti fare qualcosa come
	"select parola from dizionario where parola like '%_rima_'
(_rima_ è la rima da cercare).
Il problema del tuo programma non è tanto le 60000 parole ma le 120000
stringhe temporanee che vengono messe sullo heap...
--
Gian Uberto| main(){printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Lauri      |                        David Korn, 1987 ioccc best one liner 
(aka saint)|-------------------------------------------------------------------
em@ail: 
sa...@eng.it
 ( vedere X-nospam nello header - see X-nospam in header )

 Ciao
Sono un idiota. :-)
Io avevo messo la ProgressBar, ed č quella che dava problemi.
Infatti io ho impostato .Max a Ubound (quindi 64000) e value ad ogni
incremento.
Togliendo il .Value della ProgressBar la ricerca impiega 3 secondi, mentre
il ciclo vuoto 0 secondi (non sono stato a contare i decimi).
Io avevo fatto la prova a ciclo "vuoto" togliendo il controllo della
stringa!
Il problema era invece la Progressbar!
Grazie mille comunque, ciao!
Bald0z

> Il problema era invece la Progressbar!
Ho risolto con la tua idea:
ProgressBar.Max = 100 'fuori dal ciclo, ovviamente
      If Parola Mod (UBound(Dizionario) / 100) = 0 Then
        ProgressBar.Value = Parola * 100 / UBound(Dizionario)
      End If
Grazie!
Ciao
Bald0z

 stringhe temporanee che vengono messe sullo heap...
heap ... ossia? In memoria?
Perchè 120.000 stringhe? 60.000 !
Ciao
Bald0z

> stringhe temporanee che vengono messe sullo heap...
B> heap ... ossia? In memoria?
Si, l'area di memoria in cui vengono messe le aree di memoria allocate
dinamicamente (aka i corpi delle stringhe in VB).
B> Perchè 120.000 stringhe? 60.000 !
Si 60000 + 60000 
Right(Dizionario(Parola), Lettere) = LCase(Right(txtRima, Lettere))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1                                  + 1


 ha scritto nel messaggio
news:9qf33l$s0k$1...@serv1.albacom.net...

Beh...prego, pero' le prove che ti dicevo le ho fatte con lo stesso esatto
codice che avevi scritto in precedenza, con il max a 64.000 e tutto il
resto, e non avevo problemi lo stesso...
Vabbe', mi fa piacere tu abbia risolto, comunque sia ;-)
