Newsgroup: it.comp.lang.visual-basic
Titolo: Instr lento?

 Avete una qualche idea su come si potrebbe velocizzare?
Prova a utilizzare la split al posto della mid,
po magari col vettore che ti crea riesci a velocizzare il tutto un po'
non ne son sicuro ma magari funziona!
MIk

> Prova a utilizzare la split al posto della mid
Purtroppo lavoro su VB5 :-((

 Purtroppo lavoro su VB5 :-((
http://www.freevbcode.com/ShowCode.Asp?ID=2250
Se hai tempo potersti provare a darci un occhio,
elavorare col vettore al posto che mettere man mano le stringhe nella
matrice,
non so se velocizzi o rallenti!
Prova....
MIk

 Avete una qualche idea su come si potrebbe velocizzare?
Leggi il file, linea per linea, con: LINE INPUT #mioFile, Stringa$
e metti Stringa$ alternativamente nella matrice 1 o in quella 2.
-- 
Ciao, Mauro CB.

 e metti Stringa$ alternativamente nella matrice 1 o in quella 2.
Avevo provato, ma risulta ancora più lento :-(

 Avevo provato, ma risulta ancora più lento :-(
Come dimensioni le matrici?
-- 
Ciao, Mauro CB.

 Avevo provato, ma risulta ancora più lento :-(
Scusa, ma di quanti MB parliamo?
Prova con:
------------------------------------------------------------
Private Sub SplitOddEvenLines(ByVal FileName As String, _
                              ByRef OddLines As Collection,
_
                              ByRef EvenLines As Collection)
    On Error GoTo SplitOddEvenLines_Error
    Dim fn As Integer
    Dim aLine As String
    Open FileName For Input As #fn
    Do Until EOF(fn)
        Line Input #fn, aLine
        OddLines.Add aLine
        If EOF(fn) Then Exit Do
        Line Input #fn, aLine
        EvenLines.Add aLine
    Loop
SplitOddEvenLines_Error:
    Close #fn
End Sub
------------------------------------------------------------
hth,
Lokar
-- 
Sito Comune: 
http://www.it-lang-vb.net/
Manifesto: 
http://www.it-lang-vb.net/docs/Manifesto.txt
Statuto: 
http://www.it-lang-vb.net/docs/Statuto.txt
UGIdotNET - 
http://www.ugidotnet.org

     Open FileName For Input As #fn
Sarebbe il caso di aggiungere, prima: fn = FreeFile ;-)
-- 
Ciao, Mauro CB.

> Come dimensioni le matrici?
Sono matrici dinamiche, le ridimensiono all'occorrenza aggiungendo 10
elementi di volta in volta (ho provato anche con 100, ma non cambia)

 elementi di volta in volta (ho provato anche con 100, ma non cambia)
Sicuro che siano matrici di stringhe e non di variant?
Hai provato il codice di Lokar?
-- 
Ciao, Mauro CB.

 Sarebbe il caso di aggiungere, prima: fn = FreeFile ;-)
Naturalmente :) e' stata una svista, ho scritto direttamente
in mail, senza provare :)
fn = FreeFile
Grazie per la segnalazione :)


 Prova con:
Avevo provato qualcosa del genere, ma sembra che il metodo line input sia il
vero collo di bottiglia dell'algoritmo, quindi stavo provando a fare tutto
dalla ram, la velocità è migliorata molto, ma non abbastanza; adesso
sospetto (ma non ne sono per niente sicuro) che il collo di bottiglia sia
diventato l'Instr... o forse il Mid... mah

> Sicuro che siano matrici di stringhe e non di variant?
Of course, magari fosse quello! :-)
Comunque potrei provare con matrici statiche (anche se la cosa non mi piace
molto) che dovrebbero essere piů veloci, ma francamente non credo che il
problema sia lě, infatti un'altra sezione del programma fa delle ricerche di
un dato termine nelle matrici stesse e queste risultano quasi immediate.

 diventato l'Instr... o forse il Mid... mah
Primo anzichè Mid usa Mid$.
L'instr è piuttosto lenta se usata in vbCompareText, ma non credo sia il tuo
caso.
Riprendo l'idea dello split, ma non so quanto possa aiutarti dato che devi
farlo da codice: cerca su google->gruppi->it.c.l.vb "VB5 split": la
Microsoft ha pubblicato le funzioni stringa mancanti in VB5 tutte scritte in
VB5 stesso.
Ciao
--
Math Parser, VB.Framework : 
http://www.neodatatype.net
Sito Comune               : 
http://www.it-lang-vb.net

 VB5 stesso.
Questo lo ignoravo... buono a sapersi (Spero ci sia anche "round" che ho
sempre invidiato ;-)

 per quel che riguarda il tempo, è quello di avvio del programma
Ciao,
Scusa ma mi sfugge un dettaglio: qual'è il problema con il paginare il
file e magari caricarlo pezzo pezzo quando ti serve?
Non potresti( dico per dire ) caricarne un mega solo e poi gli altri
"on request"?
Magari carichi il primo mega subito, poi quando ti serve un altro mega, ne
carichi 3, ecc.
Andrea

 file e magari caricarlo pezzo pezzo quando ti serve?
Il programma deve confrontare una stringa con tutte quelle presenti nel file
per verificare non solo la corrispondenza del termine, ma anche un'eventuale
somiglianza. Per cui ad ogni richiesta purtroppo il file andrebbe comunque
processato integralmente.

 il file andrebbe comunque processato integralmente.
Allora scusa non puoi mandarlo in esecuzione una volta, lo tieni
avviato in memoria e vi accedi tramite COM?
Andrea

 il file andrebbe comunque processato integralmente.
Comunque non vedo perché la soluzione proposta da me non
dovrebbe andare bene... se lo trovi o ne trovi una somiglianza nel
primo mega, ok, altrimenti carichi gli altri ecc... non ti sembra carino?
Ciao
Andrea

 avviato in memoria e vi accedi tramite COM?
Beh sì, ma comunque una volta caricato in memoria il problema si risolve,
cioè il vero problema è il passaggio dei dati da file a matrice, una volta
fatto questo le ricerche nella matrice stessa sono quasi istantanee...

 quasi istantanee...
Hai pensato ad un caricamento binario?
Troppo lento anche quello?
Ed un caricamento via API di Windows?
Ciao
Andrea

> Hai pensato ad un caricamento binario?
Uso quello infatti (Get), ed in effetti è molto veloce, i guai vengono dopo,
quando devo passare i dati nella matrice, è il parsing che è lento...

 quando devo passare i dati nella matrice, č il parsing che č lento...
Utilizza un parsing binario.
Ovvero salva tutto in array di integer (caratteri unicode sono a 16 bit) e
cicla sugli elementi della matrice.
Ovviamente le comparazioni vanno fatte con altri integer (o array di
integer) che rappresentano i caratteri che cerchi.
In fase di compilazione rimuovi i controlli sui limiti degli array e avrai
un eseguibile diverse volte piů efficiente dell'interpretato.
termoPilucco.

> Utilizza un parsing binario.
Interessante come idea, anche se mi sa che complicherà il codice... ci provo
:-)


Private Sub Command2_Click()
    Dim N As Integer, T As Long, sStringa As String, lPosIn As Long, LposFin
As Long
    Dim sValori() As String
    N = FreeFile
    Debug.Print Timer
    Open "c:\temp\temp.txt" For Input As N
    sStringa = input(LOF(N), N)
    Close #N
    Debug.Print Timer
    Do
        lPosIn = InStr(lPosIn + 1, sStringa, vbNewLine)
        T = T + 1
    Loop While lPosIn <> 0
    Debug.Print Timer
    ReDim sValori(T)
    lPosIn = 1
    T = 0
    Do
        LposFin = InStr(lPosIn, sStringa, vbNewLine)
        sValori(T) = Mid(sStringa, lPosIn, LposFin - lPosIn)
        lPosIn = LposFin + 2
        T = T + 1
    Loop While lPosIn < Len(sStringa)
    Debug.Print sValori(0)
    Debug.Print sValori(T - 1)
    Debug.Print T-1
    Debug.Print Timer
End Sub
su un file di 100.000 stringhe da 105 caratteri di cui solo la prima e
l'ultima sono di tre caratteri con un P4 1.5 GHz - 130 MB - W2K - VB6 ho
queste performance:
 59011,97 inizio lettura
 59017,53 fine lettura
 59017,59 fine conteggio stringhe
oaa  prima stringa
baa  ultima stringa
 99999 dimensione matrici assegnate
 59018,44 fine assegnazione stringhe in matrice
anche facendo assegnazioni destra-sinistra non credo che ci sia un grosso
calo di prestazioni.
beppe

 ha scritto nel messaggio
news:JbPXa.227405$lK4.6...@twister1.libero.it...

Anzi, se ti basta il set ascii standard di caratteri (byte), puoi provare
così, risparmiando anche la metà della memoria:
Dim v(0 To 10) As Byte ' dove cerchi
Dim v2(0 To 1) As Byte ' cosa cerchi
' popolo gli array a manina
v2(0) = Asc("p")
v2(1) = Asc("i")
v(0) = Asc("a")
v(1) = Asc("i")
v(2) = Asc("i")
v(3) = Asc("i")
v(4) = Asc("p")
v(5) = Asc("i")
v(6) = Asc("i")
v(7) = Asc("i")
v(8) = Asc("i")
v(9) = Asc("i")
v(10) = Asc("i")
MsgBox InStrB(1, v, v2, vbBinaryCompare) ' dove c'è la prima corrispondenza
(se c'è)
termoPilucco.

 calo di prestazioni.
Comunque 7 secondi di attesa non sono pochi... su un Pentium 400 diventano
più di 20.
Inoltre in questo modo devi eseguire l'Instr due volte...

>> Avete una qualche idea su come si potrebbe velocizzare?

questo e' vero, ma la prima passata e' nell'ordine dei 6/100 di secondo,
mentre l'assegnazione alla matrice e' di 8/10 di secondo, che mi pareva
fosse il tuo problema, d'altronde, se preferisci fare tanti redim preserve a
spanna, tanti auguri.
beppe

 così, risparmiando anche la metà della memoria:
Però a questo punto mi sorge un'altro problema... come faccio a caricare
velocemente il contenuto del file nella matrice binaria?

 59017,53 fine lettura
Rappresentano il solo passaggio File --> Stringa?
Se è così il resto è davvero veloce... anche se non capisco il perché (il
tuo codice mi sembra molto simile al mio) ora ci guardo meglio...

  59018,44 fine assegnazione stringhe in matrice
In effetti ho provato il tuo codice, e hai ragione, l'Instr è molto veloce,
anche se effettuato due volte.
Quello che mi rallentava era proprio il "Redim preserve", il fatto è che
credevo di aver eliminato il problema ridimensionando la variabile ogni 100
termini trovati, ma evidentemente non era sufficiente.
Con un Athlon XP 1000 + 500 MB + Win2k ho questi valori:
 67633.85 Inizio lettura
 67634.01 File caricato in memoria
 67634.16 Linee totali calcolate
 67636.48 Assegnazione alla matrice completata
Che non sono buoni come i tuoi, ma comunque mi dimezzano i tempi :-)

 wrote in message news:%qQXa.227587

Questo è più facile:
File in modalità binaria:
Redim v(0 to LOF(file)-1)
Get #file, 1, v()


 Redim v(0 to LOF(file)-1)
... as Byte.
Volevi vedere se stavamo attenti, vero? :-)
-- 
Ciao, Mauro CB.

 Get #file, 1, v()
Grande! Credevo peggio :-)