Newsgroup: it.comp.lang.visual-basic
Titolo: Loop troppo lento

Salve
Ho bisogno di un aiuto.
Devo rendere più veloce il seguente loop:
For c = 1 To l   ' (solitamente da 1 a 17.000.000 circa)
        Get #1, c, strBuffer$
        strHEX$ = strHEX$ & Right$("0" & Hex$(Asc(strBuffer$)), 2)
        a = InStr(Hex$(Asc(strBuffer$)), strTable$)
        If a <> 0 Then
            a = a + 3
            b = InStr(a, strTable$, vbCr)
            strASCII = strASCII & Mid$(strBuffer$, a, b - a)
        Else
            If Asc(strBuffer$) < 32 Then
                strASCII$ = strASCII$ & "#"
            Else
                strASCII$ = strASCII$ & strBuffer$
            End If
        End If
Next c
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Next c
 Ma che visualizza la rappresentazione ASCII e esadecimale del contenuto di
un file?
 Non capisco la ricerca in strTable!
 Chiarisci affichè si possa ottimizzare meglio!
Ciao
 
--------------------------------
Inviato via 
http://usenet.libero.it

 Ciao
strTable è una tabella di conversione del codice Hex:
si suppone di avere il codice Hex C9, ovvero 201 (&#9556; credo),
con la tabella di codifica dovrebbe corrispondere alla lettera P.
se nella tabella non vi è contenuta nessuna informazione, inserisce
il carattere ASCII predefinito.
Il programma deve leggere da un file e deve realizzare due testi,
uno l'esadecimale puro, l'altro il testo codificato
con il codice che ho utilizzato io mi ci mette circa un minuto per arrivare
all' 1%


 strASCII$ = strASCII$ & strBuffer$
Ogni concatenazione equivale ad una copia dell'intera stringa.
Anche se l'output deve essere accodato in una stringa, conviene dichiarare
un array con le dimensioni finali e lavorare su quello.
Eventualmente alla fine poi usare StrConv() per convertire l'array in
stringa.
termoPilucco

 termoPilucco
grazie per l'aiuto
ma anche cosě si presenta lento
cosa posso fare?


 Get #1, c, strBuffer$
Quanti byte leggi ad ogni ciclo?
Conviene leggerne molti alla volta (500.000, per esempio) magari in un array
di byte.
Per convertire un byte in stringa esadecimale (o altri) puoi usare array
precedentemente inizializzati con tutti i possibili valori (sono solo 256).
In questo modo non devi eseguire conversioni di alcun tipo durante il ciclo.
termoPilucco.

 termoPilucco.


 potrei gentilmente avere un esempio?
Dim res() As Byte
ReDim res(102400)   ' sono 100 kbyte
Dim a As Long
a = FreeFile
a = 1
Open "c:\1.exe" For Binary As a
' leggo 100kbyte
Get #a, , res
Close a
termoPilucco.

  Per quanto riguarda il suggerimento di Termopilucco l'Array deve essere di
Byte eh!!!
  Mentre volevo aggiungere che per la tabella di conversione strTable, prova
ad usare una collection invece che una stringa, in questo modo risparmi la
instr e accedi direttamente in base al codice esadecimale come usandolo come
chiave.
Se proprio non va ancora be...ti consiglio di fare una dll in C.


 all' 1%
Le cose che puoi fare sono così tante che non si sa da dove cominciare !...
:-)))
Innanzitutto strtable può essere un'array di byte costruita in modo che
l'ennesimo elemento contenga l'ennesimo codice da convertire.
In questo modo ti basta prendere l'elemento indicizzato dal valore
ASCII del byte che hai letto e non devi fare instr che ti fa perdere
un sacco. Poi, per la rappresentazione esadecimale di ciò che hai
letto, puoi farlo in un secondo tempo, ma non accodando a una stringa
(tanto 1.700.000 stringhe HEX non ce le metteresti mai), ma scrivendo
su un file di testo.
--
Er Roscio.

         End If
a mio avviso ci sono due cosa da fare:
1) usare un array di byte, leggi il file in un colpo solo
2) dimensionare in anticipo la/le stringhe di output
    e usare la Mid per mettere i byte al loro posto
guarda questo esempio:
==================================
Dim S() As Byte
Dim R As String
Dim I As Long
Debug.Print "I"; Timer
    ReDim S(17000000) As Byte
    R = Space$(17000000 * 2)
    For I = 1 To UBound(S)
        Mid(R$, (I - 1) * 2 + 1, 2) = Right$("0" + Hex$(S(I)), 2)
    Next I
Debug.Print "F"; Timer
==================================
sul mio computer un celeron 1700 il risultato e' stato questo:
I 74122,15
F 74144,38
ossia 22,23 secondi
HTH
by
R

 ossia 22,23 secondi
Ho apportato qualche modifichina:
Su un celeron 1200 impiego 1,67 secondi (compilato ottimizzato p-pro
togliendo i vari controlli su array in fase di eseguibile)
Inutile dire che la soluzione non è scalabile (cresce l'utilizzo della
memoria al crescere del file originale).
Dim tt As Double
Dim i As Long
Dim j As Long
Dim res As String
tt = Timer
ReDim arrb1(0 To 255) As Byte
ReDim arrb2(0 To 255) As Byte
For i = 0 To 255
    arrb1(i) = Asc(Left(Right$("0" + Hex$(i), 2), 1))
    arrb2(i) = Asc(Right$("0" + Hex$(i), 1))
Next
ReDim s(17000000) As Byte
' s va letto da un file in modalità binaria
ReDim r(34000000) As Byte
j = 1
For i = 1 To UBound(s)
    r(j) = arrb1(s(i))
    r(j + 1) = arrb2(s(i))
    j = j + 2
Next i
Erase s
res = StrConv(r(), vbUnicode)
Erase r
MsgBox Round(Timer - tt, 2) & " Sec."
termoPilucco