Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   RTL Performance D7 vs XE7 (https://www.delphipraxis.net/181838-rtl-performance-d7-vs-xe7.html)

Stevie 11. Sep 2014 22:45

AW: RTL Performance D7 vs XE7
 
Zitat:

Zitat von himitsu (Beitrag 1272321)
Jetzt muss ich nochmal nachsehn, ob die for-in-schleife bei Arrays und Strings auch über die Enumeratoren läuft.

Nein, tut sie nicht.

Stevie 12. Sep 2014 01:03

AW: RTL Performance D7 vs XE7
 
Zitat:

Zitat von jbg (Beitrag 1272317)
Wohl eher langsamer, da sie nun mal keine Templates sondern Generics sind und man somit z.B. bei IndexOf nicht "if FList[Index] = Value then" schreiben kann, sondern einen Comparer (Interface) bemühen muss "if Comparer.Equals(FList[Index], Value)", was ein indirekter Funktionsausruf ist, der dem Compiler auch noch die Möglichkeit nimmt, Daten in CPU Register zu bunkern, vor allem bei Win32.
An die Geschwindigkeit einer TList kommt TList<T> bei weitem nicht ran.
Beispiel Worst-Case Szenario: 100.000 Einträge, letztes Element muss 10.000 Mal gefunden werden
Code:
TList: 0.299 Sekunden
TList<T>: 1.870 Sekunden

Ich nehm mal an, dass du als T eine Klasse genommen hast. Da ist nämlich das Verhalten von TList und TList<T> ein bisschen unterschiedlich und daher auch zusätzlich zu dem IComparer Overhead langsamer: TList macht einfach nen stumpfen Pointervergleich. Der Comparer bei Objekten ruft TObject.Equals auf. Und das kann sehr wohl überschrieben sein, so dass man dort nich einfach Referenzen vergleichen kann.

jbg 12. Sep 2014 07:29

AW: RTL Performance D7 vs XE7
 
Zitat:

Zitat von Stevie (Beitrag 1272328)
Ich nehm mal an, dass du als T eine Klasse genommen hast.

Falsche Annahme. Ich habe TList und TList<Pointer> benutzt. Es sollen ja gleiche Regeln gelten.

newbe 12. Sep 2014 11:09

AW: RTL Performance D7 vs XE7
 
@jbg

vielen Dank für deine interessanten Ausführungen. Deine beschriebenen Caseszenarien liegen glaub ich eher bei den meinen. Hinzu kommt noch das ich Lazy Loading nicht besonders mag und vermeide wenn ich die Möglichkeit habe. Es komm also häufiger Vor das ich beim initialisieren des Programms
Objectlisten mit mehreren Tausend Objekten pro Typ vollballere. Und da kommt es dann doch schon auf solche "Kleinigkeiten" an.

auch meine ich damals mal gehört zu haben das der Borland MM beim erweitern von Listen schneller sein sollte, weil er imm gleich 4 einträge allociert der FastMM immer einen einzigen. Trifft dies noch immer so zu?

mfg newbe

Stevie 12. Sep 2014 11:13

AW: RTL Performance D7 vs XE7
 
Zitat:

Zitat von jbg (Beitrag 1272335)
Zitat:

Zitat von Stevie (Beitrag 1272328)
Ich nehm mal an, dass du als T eine Klasse genommen hast.

Falsche Annahme. Ich habe TList und TList<Pointer> benutzt. Es sollen ja gleiche Regeln gelten.

Naja, für Pointer eine generische Liste zu benutzen ist auch ziemlich witzlos.

jbg 12. Sep 2014 11:37

AW: RTL Performance D7 vs XE7
 
Zitat:

Zitat von newbe (Beitrag 1272364)
auch meine ich damals mal gehört zu haben das der Borland MM beim erweitern von Listen schneller sein sollte, weil er imm gleich 4 einträge allociert der FastMM immer einen einzigen. Trifft dies noch immer so zu?

Das ist nicht Sache des Speichermanagers, sondern der Liste. Und die macht das immernoch so, wie zu Delphi 1.0 Zeiten. Der FastMM (der in der BorlndMM.dll seit Delphi 2006 sitzt) reserviert beim Vergrößern (Realloc) ein wenig mehr Platz, so dass ein weiteres Vergrößern ohne Anfordern von mehr Speicher erfolgen kann, was das ganze stark beschleunigt und bedingt auch die Speicherfragmentierung etwas verringert.


Zitat:

Zitat von Stevie (Beitrag 1272366)
Naja, für Pointer eine generische Liste zu benutzen ist auch ziemlich witzlos.

Ich hätte auch Integer/NativeInt nehmen können und es würde für TList<Integer> genauso schlecht aussehen. Ich wollte mir nur die Typecasts von Pointer->Integer bei TList sparen und zwei gleiche Listentypen vergleichen.
Und zum TList<TObject>. Wer überschreibt in Delphi denn TObject.Equals? Das führt nur zu seltsamen Effekten, da das es zu spät kam und jeder davon aus geht, dass ein List<TObject>.IndexOf(MyObject) den Index von MyObject liefert und nicht von einem Objekt, dass zufälligerweise die selben Daten hat.

Stevie 12. Sep 2014 11:47

AW: RTL Performance D7 vs XE7
 
Zitat:

Zitat von jbg (Beitrag 1272371)
Wer überschreibt in Delphi denn TObject.Equals? Das führt nur zu seltsamen Effekten, da das es zu spät kam und jeder davon aus geht, dass ein List<TObject>.IndexOf(MyObject) den Index von MyObject liefert und nicht von einem Objekt, dass zufälligerweise die selben Daten hat.

Nunja, TObject.Equals wird beim IEqualityComparer benutzt. Bei TList<T>.IndexOf wird aber der beim Create übergebene (oder der default) IComparer benutzt. Der kann aber durchaus auf irgendwelche Eigenschaften eines Objekts gehen (weil er auch für die Sortierung benutzt wird. Wenn ich also nen naiven Comparer baue, der nach Nachnamen und Vorname sortiert, bekomm ich bei IndexOf den ersten Hans Müller aber nicht exact denselben. Imho ein Designfehler (in Spring4D und in .Net sowieso wird der default IEqualityComparer dafür benutzt).
Wenn du das optimieren willst, dann musst du dir die IndexOf Methode überschreiben und dort mir einem case über den TypeKind die spezifischen Vergleiche laufen lassen (so werd ich diese Optimierung wohl auch in Spring4D einbauen, von daher an dieser Stelle danke, dass du mich auf dieses potenzielle Performanceproblem aufmerksam gemacht hast)

Im Übrigen benutzen wir Equals overrides bei Datenklassen durchaus (meist läuft es auf ein Id Vergleich hinaus).

newbe 12. Sep 2014 11:52

AW: RTL Performance D7 vs XE7
 
@jbg

Der FastMM ist jetzt doch drinne in XE7 oder?

@stevie

Mir ginge es beim verwenden von generics um das weniger Code schreiben / mehr Lesbarkeit, jedoch bin ich nicht gewillt dafür derartige Performanceeinbußen hinzunehmen. Den Zugriff über irgendwelche Enumeratoren find ich auch schlecht gelöst. Wenn dann bitte so wie in C#

also in der Art

foreach var item in items
item.machirgendwas;

oder

for (int i = 0; i < items.count();i++)

bla = items[i];
bla.mache irgendwas;

mfg newbe

Stevie 12. Sep 2014 12:00

AW: RTL Performance D7 vs XE7
 
Zitat:

Zitat von newbe (Beitrag 1272375)
@stevie

Mir ginge es beim verwenden von generics um das weniger Code schreiben / mehr Lesbarkeit, jedoch bin ich nicht gewillt dafür derartige Performanceeinbußen hinzunehmen. Den Zugriff über irgendwelche Enumeratoren find ich auch schlecht gelöst. Wenn dann bitte so wie in C#

also in der Art

foreach var item in items
item.machirgendwas;

Häh? Hast du überhaupt ne leise Ahnung, wie ne foreach Loop in C# funktioniert?
Richtig, mit nem Enumerator.

Worin unterscheidet sich das von:
Delphi-Quellcode:
for item in items do
  item.machirgendwas;
Außer, dass eine for in Schleife in Delphi bei einem Array (im Gegensatz zu C#, wo auch ein array IEnumerable implementiert) nicht über einen expliziten Enumerator läuft sondern vom Compiler direkt übersetzt wird.

newbe 12. Sep 2014 14:43

AW: RTL Performance D7 vs XE7
 
@stevie

naja ich kanns nicht so schreiben??? Wenn ich deinen Post vorhin richtig verstanden habe muss ich
auf das Item über irgendwelche comperator Interfaces drauf zugreifen?

dat hier meinte ich

bei IndexOf nicht "if FList[Index] = Value then" schreiben kann, sondern einen Comparer (Interface) bemühen muss "if Comparer.Equals(FList[Index], Value)", was ein indirekter Funktionsausruf ist, der dem Compiler auch noch die Möglichkeit nimmt, Daten in CPU Register zu bunkern, vor allem bei Win32.

der Unterschied fällt dir auf? gerade geschachtelte Liste und Array Acessoren finde ich hässlich.

mfg newbe


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:39 Uhr.
Seite 3 von 4     123 4      

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