Avatar billede dkklein Nybegynder
19. marts 2003 - 19:09 Der 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.

Nogen konkrete forslag til ændringer?
Avatar billede doc404 Novice
19. marts 2003 - 19:51 #1
then
  begin
    fundet := m;
    break;
  end;

break forlader løkken den befinder sig i.
Avatar billede dkklein Nybegynder
19. marts 2003 - 20:06 #2
Det gav da noget, og ihvertfald lidt mere end at lave den inderste løkke til en while som jeg også lige har prøvet.
Avatar billede borrisholt Novice
20. marts 2003 - 08:21 #3
Kom det i er træ i stedet for et Array.

Du kan fx anvende et binært træ, b træ, b+ træ, eller endnu bedere et ballanceret 2-3 træ

Jens B
Avatar billede dkklein Nybegynder
20. marts 2003 - 17:06 #4
Og hvordan gør man så det? Hvor kan jeg læse noget om det?
Avatar billede athlon-pascal Juniormester
20. marts 2003 - 19:32 #5
borrisholt -> "træ"?
Avatar billede borrisholt Novice
21. marts 2003 - 08:35 #6
OKI giv mig to oplysninger :

1)
  Hvordan ser dine elementer ud i dit array ?
2)
  Hvordan finder du ud af hvilkent element der er størst ?

Når jeg har de to oplysninger så skal jeg nok svare mere konkret !

Jens B
Avatar billede borrisholt Novice
21. marts 2003 - 08:38 #7
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.

athlon-pascal >> Følg du trygt denne tråd !

Jens B
Avatar billede arne_v Ekspert
21. marts 2003 - 22:11 #8
Hvis man kan få konstrueret en god hash funktion så bør en hash tabel
faktisk være endnu hurtigere end et træ.
Avatar billede dkklein Nybegynder
22. marts 2003 - 17:21 #9
borrisholt-> dine spørgsmål:

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.
Avatar billede borrisholt Novice
23. marts 2003 - 16:22 #10
Hmmn .. Send mig lige din kode så kigger jeg på det ....

Den bog jeg vil anbefale hedder Algorithems And Datastructures.

Jens B
Avatar billede dkklein Nybegynder
23. marts 2003 - 16:56 #11
2 arrays er defineret som følger:


  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;

  SortTrans:=SortTrans+1;
  end;
end;
Avatar billede dkklein Nybegynder
29. marts 2003 - 10:00 #12
--> Borrisholt

Ved du hvor jeg kan købe bogen du anbefalede "Algorithems And Datastructures" ?
Avatar billede dkklein Nybegynder
29. marts 2003 - 11:24 #13
Avatar billede dkklein Nybegynder
30. marts 2003 - 09:40 #14
Jeg tror vist ikke vi kommer tættere på en løsning her og nu. Jeg har bestilt den foreslået bog.

borrisholt, lav et svar så får du også point.
Avatar billede borrisholt Novice
31. marts 2003 - 13:23 #15
Nej det var godtnok ikke den jeg tænkte på, men den ser også god ud.

Jens B
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester