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. |
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:
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:
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; |
Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
Zitat:
Hab ich da:
Code:
:mrgreen:
var MyDict = new Dictionary<TKey, TValue>();
Für TKey und TValue die entsprechenden Typen einsetzen - in deinem Fall also wohl sowas:
Code:
:stupid:
var MyDict = new Dictionary<uint, Node>(1000000);
|
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: |
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.
|
Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
Zitat:
Das habe ich nicht ganz verstanden. Sollte ich mir dann so einen Typ definieren:
Delphi-Quellcode:
Und den dann stattdessen in Dict.Add nutzen?
PORPNode = ^TORPNode;
|
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));
|
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:
Anschließend wird er über eine Schleife mit Daten gefüllt:
fORPNode := TORPNode.Create;
fORPNode.Subnodes := TObjectList.Create;
Delphi-Quellcode:
Dann wird das Object zum TIntegerDictionary zugefügt: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;
Delphi-Quellcode:
Jetzt muss ich das Objekt wieder auslesen. Das geschieht so:
procedure TORPTree.AddNodeToList(Node: TORPNode);
begin fNodes.Add(Node.ID, Pointer(Node)); end;
Delphi-Quellcode:
In fRegAttrExpr.SubExpressions[3] steht laut Debugger "20958823". Wenn ich mir jetzt im Debugger fORPSubNd anzeigen lasse, dann sieht das z.B: so aus:
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;
Code:
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.
fORPSubNd.ID = 1685016144
fORPSubNd.MercLat = 2,4587345897e-307 fORPSubNd.MercLon = 0 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: |
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 ...
|
Re: Eine Frage der Performance - T(Object)List oder Dyn. Arr
Ähm... Wie jetzt genau? :gruebel: Soll ich sowas schreiben:
Delphi-Quellcode:
:gruebel:
procedure TORPTree.AddNodeToList(Node: TORPNode);
begin fNodes.Add(Node.ID, Cardinal(Node)); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:35 Uhr. |
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