Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Eine Frage der Performance - T(Object)List oder Dyn. Array? (https://www.delphipraxis.net/133884-eine-frage-der-performance-t-object-list-oder-dyn-array.html)

mschaefer 12. Mai 2009 09:42

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Dictonaries sind wirklich eine feine Sache und halten sich auch bei großen Datenräumen gut. Habe damit schon 10000 * 10000 Arrays gehabt und das ganze lief ordentlich. Es findet sich dazu auch einiges in der DP:

1. Dictonary von r2c2
2. Dictornary von alzaimer auch für NET.
3. der Zeitvergleich von alzaimer, der es auf den Punkt bringt.

Mithrandir 12. Mai 2009 10:17

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Hmm, TIntegerDictionary von alzaimar klingt doch nach dem, was ich bräuchte. Ich mein mich auch dran erinnern zu können, dass ich schonmal darüber gestolpert bin, es kam mir zumindest bekannt vor. Aber damals habe ich das noch nicht so ganz gerallt.. :mrgreen:

Mal zur praktischen Umsetzung und der Verwendung von Pointern (Gott, is das alles lange her.. :gruebel: ) folgendes Listing:

Delphi-Quellcode:
var
  Dict: TIntegerDictionary;

implementation

{... Create, Dict initialisieren, etc ...}

procedure AddNode(Node: TORPNode);
begin
  Dict.Add(Node.ID, @Node);
end;

function ReadNode(ID: Cardinal): TORPNode;
begin
  Dict.Find(ID, Result^);
end;
Ist jetzt nur ohne Test grob zusammengehackt. Wenn ich jetzt einen Eintrag lösche, was passiert dann mit den Daten, die hinter dem Pointer liegen? Muss ich mich selbst darum kümmern? Sollte ich denn weiter auf der Schiene fahren, alles in Objekte zu fassen, oder sollte ich doch lieber Records verwenden? Fragen über Fragen... :gruebel:

jfheins 12. Mai 2009 11:54

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Zitat:

Zitat von Daniel G
Wie Hansa schon erwähnte, ein Link auf irgendeine Beispielimplementation (kann auch C# sein) wäre super. :)

Ein C# Beispiel für ein Dictionary?

Hab ich da:
Code:
var MyDict = new Dictionary<TKey, TValue>();
:mrgreen:

Für TKey und TValue die entsprechenden Typen einsetzen - in deinem Fall also wohl sowas:
Code:
var MyDict = new Dictionary<uint, Node>(1000000);
:stupid:

Mithrandir 12. Mai 2009 12:00

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Moah, so war das jetzt nicht gemeint.. :lol:

Konnt ja nicht ahnen, dass C# sowas schon kann... :stupid:

Apollonius 12. Mai 2009 17:17

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Deine Umsetzung aus #22 funktioniert so nicht, da der Zeiger auf den Stack verweist. Wenn du noch mit Records arbeitest, solltest du dir mit New einen neuen Record besorgen und dann kopieren, wenn TORPNode eine Klasse sein sollte, kannst du einfach nach Pointer casten.

Mithrandir 14. Mai 2009 20:58

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Zitat:

Zitat von Apollonius
...kannst du einfach nach Pointer casten.

Hi,

Das habe ich nicht ganz verstanden. Sollte ich mir dann so einen Typ definieren:

Delphi-Quellcode:
PORPNode = ^TORPNode;
Und den dann stattdessen in Dict.Add nutzen?

Khabarakh 14. Mai 2009 22:13

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Nein, du kannst jede Referenz auf ein Objekt als Pointer interpretieren, eben mit einem Cast:
Delphi-Quellcode:
Dict.Add(Pointer(TORPNode.Create));

Mithrandir 15. Mai 2009 12:03

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Ok, danke. ;)

Allerdings habe ich das irgendwie noch nicht ganz auf der Reihe. Folgender Ablauf:

Der Node wird erstellt:

Delphi-Quellcode:
fORPNode := TORPNode.Create;
fORPNode.Subnodes := TObjectList.Create;
Anschließend wird er über eine Schleife mit Daten gefüllt:

Delphi-Quellcode:
       
       if fRegAttrExpr.Match then
          repeat
            case AnsiIndexText(fRegAttrExpr.SubExpressions[1], AllOSMElements) of

              ATTR_ID:
                begin
                  fORPNode.ID := StrToInt(fRegAttrExpr.SubExpressions[3]); //Hier steht dann z.B. 123456
                end;

              ATTR_LAT:
                begin
                  fORPNode.MercLat := StrToFloat(fRegAttrExpr.SubExpressions[3]); //Hier bspw. 53,45356645
                end;

              ATTR_LON:
                begin
                  fORPNode.MercLon := StrToFloat(fRegAttrExpr.SubExpressions[3]); //Hier bspw. 8,8234554
                end;

            end;
          until not fRegAttrExpr.MatchAgain;
Dann wird das Object zum TIntegerDictionary zugefügt:

Delphi-Quellcode:
  procedure TORPTree.AddNodeToList(Node: TORPNode);
  begin
    fNodes.Add(Node.ID, Pointer(Node));
  end;
Jetzt muss ich das Objekt wieder auslesen. Das geschieht so:

Delphi-Quellcode:
        var
ptr: Pointer;

{...}

ATTR_REF:
                  begin
                    if fORPTree.Nodes.Find(StrToInt(fRegAttrExpr.SubExpressions[3]), ptr) then
                    begin
                      fORPSubNd := TORPNode(ptr^);
                      fORPWay.SubNodes.Add(fORPSubNd);
                    end;
In fRegAttrExpr.SubExpressions[3] steht laut Debugger "20958823". Wenn ich mir jetzt im Debugger fORPSubNd anzeigen lasse, dann sieht das z.B: so aus:

Code:
fORPSubNd.ID = 1685016144
fORPSubNd.MercLat = 2,4587345897e-307
fORPSubNd.MercLon = 0
Der Eintrag wurde aber mit der o.g. genannten ID in der TIntegerDictionary gefunden, sonst wäre er ja nicht in den IF-Block gesprungen. Und theoretisch sollte in ID genau dieser Wert (20958823) stehen.

Was mache ich falsch? :gruebel:

P.S.: Ich vermute ja, ich schieße mit den Pointern falsch um mich. Aber eigentlich sieht das für mich ganz logisch aus. :gruebel:

jfheins 15. Mai 2009 12:50

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Caste mal nicht nach Pointer sondern nach Cardinal oder Integer - ich glaube die speicherst einen Pointer, der nach verlassen der Funktion ungültig wird ...

Mithrandir 15. Mai 2009 12:58

Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
 
Ähm... Wie jetzt genau? :gruebel: Soll ich sowas schreiben:

Delphi-Quellcode:
procedure TORPTree.AddNodeToList(Node: TORPNode);
  begin
    fNodes.Add(Node.ID, Cardinal(Node));
  end;
:gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:35 Uhr.
Seite 3 von 5     123 45      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz