Newsgroup: it.comp.lang.delphi
Titolo: velocità

Il codice sotto, funziona per quello che devo fare .
il problema e' la lentezza del confronto, una lentezza esagerata,
nel doppio ciclo [a] [i]
esattamente questo:   if ColonneNTP2[a]=colonneNTP1[i] then....
impiega molto tempo per confrontare 2 stringhe in [ a] e [i]
esiste un metodo piu' veloce per confrontare stringhe ?
stesso problema anche solo confronto senza salvare su file
il caricamento dei file avviene molto velocemente
con i Tfilestream, non e' che potrei confrontare
le stringhe direttamente quando carico con Tstream ?
( ovviamente i 2 stream possono essere di lunghezza diversa ).
che trovo veloce per quello che devo caricare.
Ho letto l' help e su google ma ( almeno io )
non ho trovato niente per migliorare questa lentezza di confronto
e non sono riuscito ad usare Tstream
i 2 array sono di tipo string[14] ,che prelevo dagli stream
Gradirei un esempio.
Ringrazio in anticipo.
Un saluto a tutti
Carmine
---------------------------------------------------------------------------
procedure TFmultiFile1.Massimo1;
begin
colonneTrovate:=0;
screen.cursor:=crHourglass;
progressbar1.Max:=NumCol1  ;
separatore:=chr(14);
listbox2.clear;
listbox2.visible:=false;
Savedialog1.filename:=Fnome;
if SaveDialog1.Execute then
begin
Fnome:=savedialog1.FileName;
assignfile(f1,Fnome);
rewrite(f1);
for i:=1 to numcol1 do
for a:=1 to numcol2 do
begin
if ColonneNTP2[a]=colonneNTP1[i] then
begin
 application.processmessages;
write(F1,#14,colonneNTP1[i]);
inc(colonneTrovate);
label6.caption:=intTostr(colonnetrovate);
end;
end;
end;
listbox2.items.add('Fatto 1');
label6.caption:=intTostr(colonnetrovate);
//listbox2.visible:=True;
Write(f1,'              '+IntTostr(colonnetrovate));
Write(f1,' 0             ');
closefile(f1);
screen.cursor:=crDefault;
end;

 write(F1,#14,colonneNTP1[i]);
...
-- 
Alberto Salvati
A *Neapolitan* delphi developer who is studing c# & .Net
"Dicette 'o pappece 'nfaccia 'a noce dammi 'o tiempo che pure te spertoso!"

 wrote in message
news:cmq9na$2beg$1...@newsreader2.mclink.it...


Miglora un pochino, dal tuo messaggio ( ancora grazie ),
ho capito che il componente label rallentava ancora
ho tolto proprio l' aggiornamento della label ( che stampo alla fine )
quando il confronto dava esisto positivo, ma la lentezza
e' sempre esagerata.
Secondo me, devo confrontare direttamente quando
carico con gli stream ( che velocità, 2 file con oltre 30.000 stringhe in
qualche secondo ).


1) esistono algoritmi specifici per lavori del genere.
Sottomano non ho niente ma una ricerca su google dovrebbe dare i suoi 
frutti. Cerca ad esempio  l'algoritmo Boyer-Moore.
2) xche non implementare un checksum?
Ad esempio, immagina una struttura del tipo:
type
   TQualcosa = record
      tuastringa: array[0..14] of char;
      checksum:integer
   end;
Invece di usare un array di stringhe usi un array di questo tipo record.
Quando leggi i files sorgente come stream, popoli l'array:
   variabile.tuastringa := stringlettadastream
   variabile.checksum = calcolachecksum(variabile.tuastringa);
poi, quando devi fare i confornti:
for i1 = 1 to ...
for i2 = 1 to ..
   if (array1[i1].checksum = array2[i2].checksum) and 
(array[i1].tuastringa = array2[i2].tuastringa) then
   begin
     ...scrivi su file...
Per calcolare il checksum esistono vari modi. Il + semplice potrebbe 
essere la somma dei codici ascii dei caratteri che compongono la stringa.
Ovviamente si potrebbe pensare ad usare crc o sha, ma nel tuo caso credo 
possa bastare.
Di sicuro se i checksum sono diversi le stringhe sono diverse, se invece 
i checksum sono uguali anche le stringhe potrebbero esserlo.
NB
Sono di Napoli ma vivo a Milano da circa 3 anni.
La frase della firma è il mio motto..... ;)


 La frase della firma è il mio motto..... ;)
Grazie ancora Alberto, seguirò i tuoi consigli, anche perche'
non saprei davvero come risolvere.
Ho anche alcuni libri, tra cui :
Programmare Delphi 5
Laboratorio Delphi
Usare Subito Delphi
( Ma niente in merito, mi sembra )
Dai quali ho imparato molto, molto d' aiuto
mi e' stato anche questo gruppo, con davvero
tanti esempi. Non sembrerebbe ma spesso un pezzetto
di codice letto in questo gruppo,  mi apre la fantasia per altre
cose. Un grazie anche a tutto il gruppo.
Al contrario di te sono, e abito a Casoria-Na
ma ho lavorato per 6 anni a Milano, con una grande societa' telefonica
che era in via Pirelli e anche a Cassina de Pecchi :-).
Ciao
Carmine


"carmine.vespasiano" ha scritto nel messaggio
{cut}
Primariamente eliminerei application.processmessages dal centro del ciclo 
magari spostandolo così:
for i:=1 to numcol1 do
  for a:=1 to numcol2 do begin
    if ColonneNTP2[a]=colonneNTP1[i] then begin
      write(F1,#14,colonneNTP1[i]);
      inc(colonneTrovate);
    end;
  end;
  label6.caption:=intTostr(colonnetrovate);
  application.processmessages;
end;
In questo modo dovrebbe incidere di meno, sia lo stesso processmessages che 
l'istruzione di assegnamento della label. Questo soprattutto se ritieni che 
le stringhe uguali siano molte.
Inoltre, meglio ancora, visto che usi processmessages, potresti valutare 
l'ipotesi di mettere tutte le istruzioni di aggiornamento dell'interfaccia 
utente in un Timer che, con la frequenza desiderata, valorizzi le label con 
il contenuto dei contatori.
Con l'obiettivo di diminuire il numero di cicli (e quindi di confronti), 
potresti ordinare lo stream che scorri con il ciclo piu interno prima di 
analizzarlo. In questo modo, nel test, se la stringa del ciclo esterno 
interno diventa maggiore di quello esterno puoi uscire evitando di fare 
tutti i controlli successivi. Qualcosa del genere:
for i:=1 to numcol1 do
  for a:=1 to numcol2 do begin
    if ColonneNTP2[a]=colonneNTP1[i] then begin
      write(F1,#14,colonneNTP1[i]);
      inc(colonneTrovate);
    end else
      if ColonneNTP2[a] > colonneNTP1[i] then
        break;
  end;
  label6.caption:=intTostr(colonnetrovate);
  application.processmessages;
end;
Ma sicuramente ulteriormente ottimizzabile.
Mi sembra strano che non noti grosse differenze togliendo il salvataggio su 
file (dipenderà forse da un sistema di caching di Windows), comunque, invece 
di scrivere di volta ogni singola riga potresti predisporti un terzo stream 
da salvare tutto alla fine o, alla peggio, da salvare ad ogni step del ciclo 
esterno. 

 ha scritto nel
messaggio news:qN8kd.780$n%2....@tornado.fastwebnet.it...


 che era in via Pirelli e anche a Cassina de Pecchi :-).
Inizia per S e finisce per rti, giusto? ;-)
Ci ho lavorato anche io per 4 anni come consulente
-- 
Lis
Il mio sito: 
http://lis.altervista.org
FAQ di it.comp.lang.delphi: 
http://snipurl.com/faq_icld
Gli aerei sono dei bei giocattoli, ma di nessuna utilità militare (F.Foch)

 Gli aerei sono dei bei giocattoli, ma di nessuna utilitą militare (F.Foch)

 wrote in message
news:cmsks6$ncb$1...@lacerta.tiscalinet.it...


 Carmine
A quanto pare siamo concittadini... anche io sono di Casoria !!!eheheeh!!!
Piccolo il mondo eh ?

 ha scritto nel
messaggio news:c8skd.2193$n%2.1...@tornado.fastwebnet.it...


Incredibile.
Di cognome, Volpe, a Casoria.
conosco Rino, non mi dire.....che sei parente !
Ad ogni modo la cosa  mi fà molto piacere.
Carmine
"Antonio Volpe" <stratodream@NO_SPAMfastwebnet.it> wrote in message
news:kmBkd.3008$n%2....@tornado.fastwebnet.it...


 Ciao Giorgio
    Caro Giorgio.
    Si le stringhe sono molto, possono anche arrivare a 2.000.000
    3.000.000. La lentezza inizia gia su 2 file intorno alle 30.000 stringhe
    in entrambi.
    Per il write, anche elaborando solo in memoria, i tempi come ho
    fatto fino ad oggi, non migliorano, oppure magari migliorano ma
    forse la differenza e minima e impercettibile, insomma resta la lunga
attesa
----------------------------------------------------------------------------
--
    Per abitudine le provo tutte, adesso sono partito
   dal  consiglio di Alberto e cioe' quello di provare
    a confrontare un integer.
    Quindi nel record, che creo molto velocemente grazie al TFilestream
     nel confronto, il CHECKSUM nel confronto corrisponde alla stringa
     nel record.
    Inoltre come Alberto mi fà capire, potrebbero
    esserci piu' stringhe uguali ma diverse, con lo stesso CHECKSUM. Quindi
    oltre a tramutare in numero il codice ascii, assegno un numero alla
    posizione del carattere. Ho 14 caratteri per stringa il carattere 1
    ha posizione 1, fino al 14. Non mi resta che provare se sono piu'
    veloce. Poi provo tutti gl altri metodi consigliati come in ordine di
ricezione.
    Provo  con un esempio
    prediamo le 2 stringhe sotto.
    11111111111144
    11111111111414
    La somma se trasformiamo in numeri ogni singolo carattere
    è = 20. Quindi stessa somma ma stringa diversa, farei un confronto
    sbagliato, giusto ?. Stesso problema si avrebbe se trasformo in numero
il singolo ascii
    Allora aggiungo : Il  carattere  1 in prima posizione vale 1 l' ultimo
14
    il primo carattere  2 vale 21, l' ultimo 2 vale 34
    il primo carattere  4 vale 41, l' ultimo 54 vale
    In questo modo dovrei essere sicuro ( credo ), di non copiare
    stringhe diverse ma con la stessa somma. Questo nell' uso del
    CHCKSUM. ( Numero intero per il test della somma Stringa )
     Una cosa ho dimenticato di dirvi.
     Le stringhe sono sempre composte da caratteri 1,2,4
  --------------------------------------------------------------------------
--
   Ciao
   Carmine

Sappi che molto è stato fatto per trovare formule che garantissero una 
relazione 1:1 tra valore in ingresso e hash calcolato.
Esistono algoritmi standard come md5, sha, blowfish che *riducono* di 
molto la possibilità di duplicazione.
Intanto, se ti va, puoi fare un test per verificare se il checksum 
calcolato come fai tu puo produrre valori uguali partendo da stringhe 
diverse.
hai 3 simboli per 14 elementi, ovvero 3 elevato alla 14.
Non è un numero elevatissimo: 4,782,969
Se cerchi nei vecchi post del ng trovi un metodo per calcolare queste 
sequenze. In fonso si tratta di ciclare da 1 a 4,782,969, prendere il 
numero e convertitolo in base 3 (si, tre, non due!) ottenenedo 14 cifre:
indice 0 = 11111111111111
indice 1 = xxxxxxxxxxxxxx
etc etc etc
4,782,969 = 44444444444444
ciclando calcoli il valore hash (ora è piu giusto chiamarlo cosi che 
crc..) della stringa ottenuta e tenti di salvarlo su qualcosa, che so un 
cds con indice unique e trappi l'eccezione se capita.
Che io sappia, non esiste una formula perfetta....
-- 


 Carmine
In realta sono l'unico volpe, ho detto Casoria ma non ho precisato Arpino.
Antonio.

 una ventina di anni addietro
  .Sempre saputo, come il formato sch e altro ancora diciamo hai
   iniziato il percorso
   Poi leggo/archivio il giornale la schedina da quando scrivevi listati
   in turbopascal. Adesso il giornale ha preso una strada diversa, ma anche
   questo è un altro discorso :-)
   Sai apprezzo molto il formato NTP, rispetto ad altri per la sua facile
   conversione in altri formati.
   Ciao
   Carmine

 SERVERS
1000GB data Transfer included
Redhat, Debian, SUSE, FreeBSD and Windows Servers
www.globalregister.net

Anche per informare chi gentilmente mi ha risposto.
Vado..
Il problema sono i molti confronti che il povero PC di turno
deve fare.
Esempio :
2 file da 30.000 stringhe oppure numeri
risultano 30.000 * 30.000 confronti decisamente troppi
anche se il risultato sarà perfetto, l' attesa è lunga.
A nulla è valso ( purtroppo ) gli ottimi sufferimenti per velocizzare
le operazioni di ciclo,
Per adesso il metodo migliore ( sembra ), è quello consigliato
da Alberto. Ovvio per il formato che devo confrontare.
Le stringhe massime possono essere 14^3
quindi al massimo 4782969 ( ovviamente nel mio caso )
come giustamente calcolato da Alberto.
Creare un array [1..4782969]
 array[1]            = 11111111111111
array[4782969]:=  44444444444444
Una volta associato  la giusta stringa all' array
( e qui ci sto appunto lavorando )
anche in caso si stringhe formate da 4.000.000
eseguo un solo ciclo di confronto  da 1 a 4782969, operazione
velocissima ( qualche secondo ).
Quindi dopo aver popolato/associato l' array con un ciclo fino a 4782969
carico i due file con Tfilestream e faccio l' opposto
dalla stringa trasformo in numero di posizione se corrisponde
altro esempio la colonna è 11111111111111 devo valere posizione 1
la colonna 11111111111112 deve valere posizione 2.
Non resta che trovare il miglior metodo, per generare in input
la giusta conversione e collocazione della colonna, giusto ?. Giusto :-)
sperando che il tutto sia chiaramente esposto.
.
P.S.
Ho letto in qualche messaggio vecchio del gruppo che ci possono essere
problemi con MD5 e similari. confermate ?.
Un saluto a tutti.
Carmine