Avatar billede ugge Nybegynder
11. november 2000 - 22:53 Der er 6 kommentarer og
1 løsning

TList en hash?

Lige et let spm. Er TList (fra delphi 4) implementeret som hashtabel, eller minder den om STL\'s Vector? Hvis jeg f.eks putter to objekter ind på henholdsvis TList.Items[0] og TList.Items[10000], er der så allokeret 9999 tomme pladser?

MVH Ugge
Avatar billede pellelil Nybegynder
12. november 2000 - 08:39 #1
Der vil (i teorien) være allokeret 9999 tomme pladser. En TList allokere hukommelse til et \"array\" hvori der kan være X-antal pointere som hver især peger på sit object.

I teorien vil den hukommelse som en TList allokere fylde 4 x antal-poster (eftersom en pointer er 4 bytes), men den måde hvorpå en TList fungere så kan du ikke helt regne med dette, da den allokere hukommelse i blokke (således at den ikke skal afsætte plads hver eneste gang man tilføjer et objekt). Her har du den \"Grow-methode\":
<SNIP>
procedure TList.Grow;
var
  Delta: Integer;
begin
  if FCapacity > 64 then
    Delta := FCapacity div 4
  else
    if FCapacity > 8 then
      Delta := 16
    else
      Delta := 4;
  SetCapacity(FCapacity + Delta);
end;
</SNIP>

Hvis du på forhånd ved at din liste skal indeholde 10000 elementer, så start med at sætte din Capacity (TListXX.Capacity := 10000;) dette vil spare den for at kalde Grow mens du indsætter poster.
Avatar billede ugge Nybegynder
13. november 2000 - 00:15 #2
Hvis min list nu kun skal indholde 2 elementer. En på plads 0 og en på plads 10000. I et array vil der allokeres 10001 * 4 bytes, mens en hashtabel kun allokerer til de 2 * 4 bytes. Jeg vil gerne vide: Hvormeget allokerer TList. Hvordan er den implementeret?? Som en wrapper om et array? Som et array med tilhørende hash-funktion?? Som kædet liste???
Spørgsmålet er ikke så vigtigt for mig da jeg netop har lavet min egen hash, men pointene går stadig til den der kan svare på om TList er:

1) En hash-tabel, eller...

2) wrapper om et array a\'la Vector i C++

MVH Ugge
Avatar billede pellelil Nybegynder
13. november 2000 - 08:02 #3
Jeg prøver igen:

En TList indeholder IKKE en hashtabel. Den indeholder derimod en pointer til et array af pointere (se nedenstående). Den plads der allokeres til dette array afhænger af hvor mange pointere der skal være i arrayet. I dit tilfælde hvis du vil insætte de to som henholds element nr. 0 og 10000 så skal der mindst allokeres 10001 * 4 bytes.

<SNIP>
const
  MaxListSize = Maxint div 16;
type
  PPointerList = ^TPointerList;
  TPointerList = array[0..MaxListSize - 1] of Pointer;
</SNIP>

Dog er der ingen der forhindre dig i at gøre det på en anden måde:
<SNIP>
type
  ElmClass=Class
  FElementNummer : Integer;
  end;
var
  List : TList;
  Element : ElmClass;
begin
  List := TList.Create;
  Element := ElmClass.Create;
  Element.FElementNummer := 0;
  List.Ass(Element);
  Element := ElmClass.Create;
  Element.FElementNummer := 10000;
  List.Ass(Element);
<SNIP>

På denne måde har du kun indsat 2 elementer, så teoretisk har TList kun afsat 8 bytes. Men hvorvidt dette kan bruges eller ej, komme helt an på hvad du skal bruge din liste til (alt-andet-lige ville jeg aldrig bruge en TList til at gemme kun element nr, 0 og 10000).
Avatar billede pellelil Nybegynder
13. november 2000 - 13:40 #4
<LOL> Øhh prøv at erstatte \"Ass\" med \"Add\" så bliver det nok nemmere både at læse og at oversætte  :-)
Avatar billede ugge Nybegynder
13. november 2000 - 20:17 #5
Tak for svaret pellelil. Jeg skal bruge en container til at indeholde et par hundrede elementer med index der går fra nul til ca. 1 mio., så en hash ville være perfekt. Nu har jeg selv lavet en og mit problem er løst. TList er åbentbart ikke way to go :).
Avatar billede pellelil Nybegynder
14. november 2000 - 07:31 #6
Du kunne have valgt at bruge en TStringList. Denne kan både indeholde en string liste, men samtidig en \"Object liste\". Du kunne således bruge \"streng-delen\" til at styre sorteringen. Du kan selvfølgelig ikke bare tage fat i element nummer 45, men skal først finde ud af hvor denne er. Dette gøres vha. TStringListen\'s \"find\" som alt-andet-lige er (jeg gætter her) implementeret som en binær-søge-metode hvorfor dit overhead er minimal.

Jeg har aldig selv være forelsket i hashtabel\'er da de teoretisk kan ende op med 2 elementer på samme plads (dog er der også råd for det). Jeg ville personligt nok vælge at bruge ovenstående (men vi har da heldivis flere muligheder at vælge imellem så hvis du fortrækker hashtables - by all means).
Avatar billede ugge Nybegynder
14. november 2000 - 17:18 #7
Hash tabeller er MEGET hurtigere end lineær søgning. Det er rigtigt at et antal elementer vil ligge på samme plads, dette kan løses f.eks. med en kædet liste. Det er lidt besværligt, men jeg kan meget godt lide resultatet.
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