Objekttyp in C++ zur Laufzeit ermitteln

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.

Re: Objekttyp in C++ zur Laufzeit ermitteln

Beitragvon Schrompf » 07.04.2017, 00:23

Goderion hat geschrieben:Jedes Objekt kümmert sich dann um die eigene Löschung, was einen virtuellen Destruktor überflüssig macht.
Am Anfang hat mich das etwas genervt, für jedes Objekt extra eine Delete-Funktion zu implementieren.
Aber im Nachhinein hat sich das als extrem nützlich erwiesen, vor allem in Kombination mit einem eigenen Speichermanager.


Aua aua aua. Sorry, aber das ist so falsch, dass ich gar nicht weiß, wie ich das erklären soll. Du erfindest also den Destruktor neu, nur halt manuell. Du hast keine Garantien für nix, keinen Compiler-Support, aber nen eigenen Heap, den Du mit nem Custom Allocator auch kriegen könntest. Und hast Du Deinen eigenen Heap denn jemals profiled? Weißt Du überhaupt, ob er tatsächlich schneller ist? Immerhin trittst Du gegen eines der am besten getesteten und optimierten Code-Teile der CRT an.

Nuja, mach, wie Du magst. Aber das Ganze riecht doch heftig nach Not Invented Here.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.
Benutzeravatar
Schrompf
Thomas Ziegenhagen
Moderator
 
Beiträge: 3627
Registriert: 26.02.2009, 00:44
Wohnort: Dresden
Benutzertext: Lernt nur selten dazu

Re: Objekttyp in C++ zur Laufzeit ermitteln

Beitragvon Goderion » 07.04.2017, 01:37

Krishty hat geschrieben:Hast du globale Optimierungen (LTCG) aktiviert, so dass das Konstruktorverhalten bekannt ist? Visual C++ kapituliert oft vor Zeigern; wenn du es als lokale Variable erzeugst, funktioniert es aber manchmal.

Vielen Dank für den Tip, habe LTCG mal aktiviert. Es läuft jetzt etwas schneller, aber der vtable wird immer noch genutzt, NARF!

Schrompf hat geschrieben:Aua aua aua. Sorry, aber das ist so falsch, dass ich gar nicht weiß, wie ich das erklären soll. Du erfindest also den Destruktor neu, nur halt manuell.

Ich versehe dich nicht so richtig, glaub ich. Wieso erfinde ich den Destruktor neu? Die Objekte haben weiterhin ihre Destruktoren, die auch aufgerufen werden.

Schrompf hat geschrieben:Du hast keine Garantien für nix, keinen Compiler-Support, aber nen eigenen Heap, den Du mit nem Custom Allocator auch kriegen könntest.

Was für Garantien? Was für Compiler-Support?
Ich bin mir nicht sicher, ob ein Custom Allocator meinen Speichermanager ersetzen kann, bzw. es sind mehrere Speichermanager.

Schrompf hat geschrieben:Und hast Du Deinen eigenen Heap denn jemals profiled? Weißt Du überhaupt, ob er tatsächlich schneller ist? Immerhin trittst Du gegen eines der am besten getesteten und optimierten Code-Teile der CRT an.

Ich habe das mal mit 1.000.000 Objekten getestet (new und delete).
Mit Speichermanager:
9947 µs
9819 µs
9917 µs
9930 µs
Ohne:
65394 µs
65708 µs
65360 µs
65385 µs

Es geht auch nicht nur um die Performance, durch den Speichermanager kann ich immer gut sehen, was im Speicher gerade los ist. Beim Testen finde ich das extrem hilfreich.

Schrompf hat geschrieben:Nuja, mach, wie Du magst. Aber das Ganze riecht doch heftig nach Not Invented Here.

Wonach es auch immer riechen mag, es läuft extrem stabil und sicher. ;-)

EDIT:
Ich habe jetzt auch mal die Performance vom shared_ptr mit meiner Lösung verglichen.
Test zum shared_ptr:
Code: Ansicht erweitern :: Alles auswählen
        for (int i = 0; i < 1000; ++i)
        {
                std::shared_ptr<ClassTest> P[1000];

                for (int j = 0; j < 1000; ++j)
                {
                        P[j] = std::make_shared<ClassTest>();
                }

                for (int x = 0; x < 100; ++x)
                {
                        std::shared_ptr<ClassTest> PP[1000];

                        for (int j = 0; j < 1000; ++j)
                        {
                                PP[j] = P[j];
                        }
                }
        }

Ergebnis:
1949918 µs
1942421 µs
1940712 µs
1940622 µs

Test zum OLE-Style:
Code: Ansicht erweitern :: Alles auswählen
        for (UInt32 i = 0; i < 1000; ++i)
        {
                spObject P[1000];

                for (UInt32 j = 0; j < 1000; ++j)
                {
                        P[j] = new ClassTest();
                }

                for (UInt32 x = 0; x < 100; ++x)
                {
                        spObject PP[1000];

                        for (UInt32 j = 0; j < 1000; ++j)
                        {
                                PP[j] = P[j];
                        }
                }
        }

Ergebnis:
1015445 µs
1017010 µs
1018666 µs
1015513 µs

Der shared_ptr ist zu meiner Überraschung langsamer, liegt vielleicht daran, dass der shared_ptr auch einen "Weak-Counter" hat.
Goderion
 
Beiträge: 58
Registriert: 16.09.2012, 12:02
Alter Benutzername: Goderion

Re: Objekttyp in C++ zur Laufzeit ermitteln

Beitragvon Gene » 07.04.2017, 14:31

Goderion hat geschrieben:Der shared_ptr ist zu meiner Überraschung langsamer, liegt vielleicht daran, dass der shared_ptr auch einen "Weak-Counter" hat.

Ich tippe auf thread sicherheit.Der std::shared_ptr ist thread sicher, das heißt mehrere threads können "zeitgleich" kopien erstellen und der reference count wird korrekt angepasst. Deine Lösung ist nicht Thread sicher.
Gene
 
Beiträge: 25
Registriert: 22.05.2003, 11:26

Re: Objekttyp in C++ zur Laufzeit ermitteln

Beitragvon Schrompf » 07.04.2017, 14:48

Die selbe Vermutung habe ich auch beim Heap. Gegenüber dem generischen Heap kann man eigentlich nur mit Kontextwissen bei speziellen Anwendungsfällen was rausholen. Dazu sind Custom Allocators ja da, nöch :-)

Aber nuja, jeder wie er mag.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.
Benutzeravatar
Schrompf
Thomas Ziegenhagen
Moderator
 
Beiträge: 3627
Registriert: 26.02.2009, 00:44
Wohnort: Dresden
Benutzertext: Lernt nur selten dazu

Re: Objekttyp in C++ zur Laufzeit ermitteln

Beitragvon Krishty » 07.04.2017, 15:39

Naja; der generische Heap wird auch durch andere Sachen ausgebremst – Prüfdaten gegen Heap Overflow Attacks und so. Stimmt aber schon; HeapAlloc() sollte meist unter 100 Takten liegen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
 
Beiträge: 6141
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy

Re: Objekttyp in C++ zur Laufzeit ermitteln

Beitragvon Goderion » 07.04.2017, 16:04

Gene hat geschrieben:
Goderion hat geschrieben:Der shared_ptr ist zu meiner Überraschung langsamer, liegt vielleicht daran, dass der shared_ptr auch einen "Weak-Counter" hat.

Ich tippe auf thread sicherheit.Der std::shared_ptr ist thread sicher, das heißt mehrere threads können "zeitgleich" kopien erstellen und der reference count wird korrekt angepasst. Deine Lösung ist nicht Thread sicher.

Jo, das scheint es gewesen zu sein. Benutze ich die thread sichere Version, ist der shared_ptr etwas schneller, was wohl an den fehlenden virtual calls liegt.
2206904 µs
2206011 µs
2202900 µs
2205281 µs

Bei mir laufen 5 Threads (Main, Input, Video, Sound und Logik), aber ich brauche an nur sehr wenigen Stellen thread sichere Objekte.

Schrompf hat geschrieben:Die selbe Vermutung habe ich auch beim Heap. Gegenüber dem generischen Heap kann man eigentlich nur mit Kontextwissen bei speziellen Anwendungsfällen was rausholen. Dazu sind Custom Allocators ja da, nöch :-)

Mein Speichermanager ist nicht thread sicher, was natürlich einer der Gründe sein wird, warum ich damit schneller Objekte/Speicher reservieren und wieder freigeben kann. An den Stellen, wo ich den Speichermanager nutze, ist auch keine thread-Sicherheit nötig.

Schrompf hat geschrieben:Aber nuja, jeder wie er mag.

Immer so ein Abschlusssatz... ;-)
Nur weil ich nicht immer den aktuellen Standard nutze, bedeutet das nicht, dass es gleich Kagge ist. Die Unreal Engine nutzt z.B. auch keine std::shared_ptr.
Ich will jetzt die Unreal-Engine nicht mit meinem Programm vergleichen oder das Können der Unreal-Entwickler mit meinen Fähigkeiten, das wäre absurd,
aber nur weil etwas nicht dem Standard entspricht, es gleich zu verteufeln, halte ich für falsch.

Ich überlege auch schon seit gestern, ob und wo ich den std::shared_ptr in meinem Programm sinnvoll einsetzen kann, habe auch schon etwas mit dem shared_ptr experimentiert,
aber aktuell sehe ich ihn ihm keinen Nutzen für mich, vielleicht unter anderen Bedingungen in einem anderen Programm.

Ich bedanke mich für die Antworten und Hinweise, die ihr mir gegeben habt und werde weiter darüber nachdenken.
Goderion
 
Beiträge: 58
Registriert: 16.09.2012, 12:02
Alter Benutzername: Goderion

Re: Objekttyp in C++ zur Laufzeit ermitteln

Beitragvon Schrompf » 07.04.2017, 16:28

Goderion hat geschrieben:Ich bedanke mich für die Antworten und Hinweise, die ihr mir gegeben habt und werde weiter darüber nachdenken.


Nur zur Klarstellung, damit das nicht falsch stehen bleibt: Ich finde es Mist, was Du da baust. Aber das ist nur meine persönliche Meinung. Wenn Du Dir Deiner Sache sicher bist, dann muss Dich das nicht stören. Du kannst in Deinem eigenen Code machen, was Du willst. Mehr sollen meine Nachsätze nicht sagen.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.
Benutzeravatar
Schrompf
Thomas Ziegenhagen
Moderator
 
Beiträge: 3627
Registriert: 26.02.2009, 00:44
Wohnort: Dresden
Benutzertext: Lernt nur selten dazu

Vorherige

Zurück zu Algorithmen und Datenstrukturen

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste