Moin!
Gammatester hat folgendes geschrieben : |
Jetzt muß es halt das aller-allerletze Mal sein (das ist beliebig iterationsfähig, also bitte keine weiteren guten Ratschläge). |
Hey, das erinnert mich an Terry Pratchett, Trolle und Zählen: 1, 2, 3, Viele, Viele-1, Viele-2, Viele-3, Viele-Viele, ...
Gammatester hat folgendes geschrieben : |
Ich sehe nirgends ein @ |
Ja, das ist korrekt, ich wollte es vereinfachen.
Gammatester hat folgendes geschrieben : |
Die diskutierte Situation ist Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var Int: Integer; Float: Double; type PDouble = ^Double; begin PDouble(@int)^ := Float; | |
Nein, ist sie nicht, denn der generierte Pointer zeigt bei dir auf einen einfachen Datentyp (und das auch noch auf dem Stack), bei mir
immer auf den Anfang eines dynamischen Strings. Da ein Heap-Block aber immer min. 16 Bytes groß ist, ich aber nur einfache Datentypen typkonform gecastet so "verwerflich" da rein schreibe, kann es prinzipiell nicht zu einem Problem kommen - selbst wenn die Typlänge nicht passen sollte (was ich durch Vermeidung von generischen Typen ausgeschlossen haben sollte).
//EDIT: ---------- (hatte jetzt erst Zeit, um ausführlicher auf die "diskutierte Situation" einzugehen)
Zunächst mal hast du Recht, wenn du sagst, dass ich beim Verzicht auf generische Typen auch kein
Integer verwenden darf. Ja, der Punkt geht voll auf mein Sündenkonto (ich bin ketzerischer Weise davon ausgegangen, dass die Sprache Delphi es nicht mehr erleben wird, dass Integers 64 Bit breit sind). Ich bereue und werde deshalb im Folgenden
Longint dafür verwenden.
Kommen wir zur Analyse der wirklich diskutierten Version(en):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| SetLength(BinMsg,4); PLongint(@BinMsg[1])^ := MyLongint; SetLength(BinMsg,sizeof(MyLongint)); move(@BinMsg[1], MyLongint, sizeof(MyLongint)); |
Abstrahieren wir mal das, was da im Prinzip passiert:
- Speicherplatz reservieren
mein Ansatz: garantierte Basistypmenge (Konstante laut Doku)
dein Ansatz: dynamisch ermittelte Größe von Basistypen entsprechen immer der Basistypgröße (ersetzt der Compiler durch eine Konstante)
Fazit: gleichwertig
- Pointer generieren
mein Ansatz = dein Ansatz, identisch -> @BinMsg[1]
Fazit: gleichwertig
- Daten schreiben
mein Ansatz: Pointer-Typecast auf einen Basistyp, einfache Schreiboperation der CPU
dein Ansatz: Kopierschleife, gesteuert durch eine vom Compiler eingesetzt Konstante für die Basistypgröße
Fazit: mein Ansatz ist performanter, da die CPU das durch eine native Operation abwickeln kann, dein Ansatz ist eine Schleife, Aufwand: O(1) < O(n)
- Ergebnis aus Sicht deines Ansatzes: gleichwertig - gleichwertig - höherer Aufwand

Abschließend noch etwas zu dem von dir angepassten Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var Int: Integer; Float: Double; begin PDouble(@Int)^ := Float; var Int: Integer; Float: Double; begin move(@Int, Float, SizeOf(Float)); |
Das sollte das von dir modifizierte Beispiel ad absurdum führen, da deine Version genau so zielsicher Speicher überschreibt, wie meine. Ich wollte mit dem Beispiel ursprünglich zeigen, dass der Compiler bei einem Pointer-Typecast sehr wohl die Schreiboperation typensicher ausführt. Dass der referenzierte Pointer natürlich keiner Typprüfung unterliegt, ist ja wohl klar (oder: der Sinn der Sache). Deshalb muss ich die Unterstellung, ich wolle absichtlich etwas falsch verstehen, an dieser Stelle klar an dich zurückgeben!
Gesamtfazit: Unsere Ansätze sind funktional gleichwertig, meiner ist aber performanter. Wie du also darauf kommst, dass dein Ansatz prinzipiell "besser" sein soll, ist mir nicht klar. "Universeller einsetzbar" im Austausch gegen "besser" fände ich angemessen.
Dass das ganz konkret auf mein Tutorial bezogen "keine gute Idee" ist (OK, das habe ich in dem betreffenden Beitrag leider nicht dazu geschrieben, allgemein ist diese Aussage sicher nicht korrekt - hier scheint unser Hauptmissverständnis zu liegen; sorry also dafür), hat zwei Gründe:
- keine generischen Typen, da der FrameAssembler TCmdSeq (das ist nämlich die Stelle im Tut, um die es hier wirklich geht) vorhersagbare Framegrößen erzeugen soll (by-design)
- dein Ansatz, Basistypen per move() zu verarbeiten, mir (im Sinne des Tuts) zu nahe legt, das ganze auch mit Verbunddatenstrukturen zu tun, womit die FrameAssembler-Klasse ihre Allgemeingültigkeit verliert, weil sie zu stark ausdifferenziert
cu
Narses
There are 10 types of people - those who understand binary and those who don´t.