19. marts 2003 - 19:09Der er
13 kommentarer og 2 løsninger
Optimering af søgning
Jeg har et array med op til 100.000 elementer måske endnu flere. Jeg skal have optalt alle elementerne for unikke transaktioner.
Pt har jeg følgende dobbelte for løkke som er meget ineffektiv:
For n:=0 to TransCount-1 do with DBquery[n] do begin fundet:=-1; For m:=0 to SortTrans-1 do with DBquerystats[m] do begin if (DBquery[n].query=DBquerystats[m].query) and (DBquery[n].keytype=DBquerystats[m].Keytype) and (DBquery[n].key=DBquerystats[m].Key) then fundet:=m; end; end;
Hver gang der findes en ny unik transaktion øges antallet af genneløb for den inderste løkke så det kører langsommere og langsommere.
Hvad er den bedste metode til at optimere en sådan rutine? Eksempelvis kunne jeg godt tænke mig at kunne forlade den inderste løkke når der er fundet et hit, men jeg har ikke fundet ud af hvordan jeg gør det id over at lave for løkken om til en while løkke.
dkklein >> Hvor man kan læse om den slags ? Tjooo køb en matematisk orienteret programmerings bog. Jeg vender tilbage med en tittel senere, nok i morgen.
1: elementerne er tekst elementer af varierende længde. Ved een type søgning er det 1 til 7 karakterer der søges efter. Ved en anden søgning er det fra 10 til 100+ karakterer der søges efter.
2: Det gør jeg ikke. Alt er gemt i et array of records i "tilfældig" rækkefølge.
DBquery : Array of record iPid : integer; TransType, Date, Time, PID, where, filename, key, weight, keytype, records, seconds, query, sortfields, extracttime, sorttime, db12 : string; end; DBquerystats : Array of record Query,Filename,Keytype,Key,Seconds,PID : string; Antal : integer; iPid : integer; end;
Denne kode er ændret på grundlag af et forslag jeg har fået andetsted men det gjorde rutinen langsommere.
For n:=0 to pred(TransCount) do begin fundet:=pred(TransCount);
if (donotcount.Checked=false) then begin while fundet>=0 do if (DBquery[n].query=DBquerystats[fundet].query) and (DBquery[n].keytype=DBquerystats[fundet].Keytype) and (DBquery[n].key=DBquerystats[fundet].Key) then break else dec(fundet);
end; if fundet>-1 then DBqueryStats[fundet].Antal:=DBqueryStats[fundet].Antal+1 else begin DBqueryStats[SortTrans].Antal:=1; DBqueryStats[SortTrans].PID:=DBquery[n].PID; DBqueryStats[SortTrans].iPid:=strtoint(DBquery[n].PID); DBqueryStats[SortTrans].Query:=DBquery[n].query; DBqueryStats[SortTrans].Filename:=DBquery[n].filename; DBqueryStats[SortTrans].Keytype:=DBquery[n].keytype; DBqueryStats[SortTrans].Key:=DBquery[n].key; DBqueryStats[SortTrans].Seconds:=DBquery[n].seconds; SortTrans:=SortTrans+1; end; end;
Her kommer min egen version af ovenstående:
For n:=0 to TransCount-1 do with DBquery[n] do begin fundet:=-1; For m:=0 to SortTrans-1 do with DBquerystats[m] do begin if (DBquery[n].query=DBquerystats[m].query) and (DBquery[n].keytype=DBquerystats[m].Keytype) and (DBquery[n].key=DBquerystats[m].Key) then fundet:=m; end; if fundet>-1 then DBqueryStats[fundet].Antal:=DBqueryStats[fundet].Antal+1
else begin DBqueryStats[SortTrans].Antal:=1; DBqueryStats[SortTrans].PID:=DBquery[n].PID; DBqueryStats[SortTrans].Query:=DBquery[n].query; DBqueryStats[SortTrans].Filename:=DBquery[n].filename; DBqueryStats[SortTrans].Keytype:=DBquery[n].keytype; DBqueryStats[SortTrans].Key:=DBquery[n].key; DBqueryStats[SortTrans].Seconds:=DBquery[n].seconds;
Nej det var godtnok ikke den jeg tænkte på, men den ser også god ud.
Jens B
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.