[C++] Speicherfreigabe bei statischem Singleton
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Da magst du in den meisten Fällen Recht haben, ich persönlich habe aber z.B. absolut keinen Bock a) zentrale Log-Einrichtungen und b) zentrale Dateisystem-bezogene Daten überall per Parameter oder gar Members zu verteilen. ;-)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Ich hätte mich schon einmal entgegen all meiner Prinzipien fast dazu hinreißen lassen genau solche Dinge als Singleton anzulegen. Du glaubst gar nicht wie glücklich ich nach ein paar Monaten war dass ich das doch nicht getan hab ;)
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Na dann, ich bin jedenfalls seit Jahren glücklich damit. :P Viel interessanter wäre aber, wie du es denn am Ende stattdessen gemacht hast. ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Na so wie mans Eben macht: Wenn ein Objekt ein andres benötigt bekommts ne Referenz drauf ;)
Das ist genau Problem mit Singleton: Es wird ständig als globaler Zugriffspunkt auf ein Objekt missbraucht. Genau das ist aber nicht der Sinn von Singleton, steht sogar explizit so im GoF Buch. Leider ist das der wohl am meisten missverstandene Satz der Softwareentwicklung...
Das ist genau Problem mit Singleton: Es wird ständig als globaler Zugriffspunkt auf ein Objekt missbraucht. Genau das ist aber nicht der Sinn von Singleton, steht sogar explizit so im GoF Buch. Leider ist das der wohl am meisten missverstandene Satz der Softwareentwicklung...
Zuletzt geändert von dot am 01.06.2011, 15:30, insgesamt 2-mal geändert.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Iih, das kostet dann ja für jedes Objekt im ganzen Programm extra Speicher... ;) Ich weiß, dass das nicht der eigentliche Sinn von Singletons ist. Ich kann es ja ab sofort "globales Singleton" nennen, ein gänzlich neues und innovatives Entwurfsmuster, welches das klassische Singleton mit der klassischen globalen Variable verbindet. :mrgreen:
Nachtrag zum Post untendrunter: Bei mir loggen aber praktisch alle Objekte.
Nachträgliche Korrektur: Auch hier habe ich das Singleton-Muster mit der typischen statischen Klasseninstanz in der entsprechenden klassischen Singleton-Zugriffsmethode vermengt, welche ich eigentlich bereits zu diesem Zeitpunkt nicht länger als Singleton, sondern in einer entsprechenden freien Funktion und ohne Konstruktionsbeschränkung implementiert hatte. Eine ausführliche Diskussion mit Beispielen und Vergleich findet sich gegen Ende dieses Threads.
Nachtrag zum Post untendrunter: Bei mir loggen aber praktisch alle Objekte.
Nachträgliche Korrektur: Auch hier habe ich das Singleton-Muster mit der typischen statischen Klasseninstanz in der entsprechenden klassischen Singleton-Zugriffsmethode vermengt, welche ich eigentlich bereits zu diesem Zeitpunkt nicht länger als Singleton, sondern in einer entsprechenden freien Funktion und ohne Konstruktionsbeschränkung implementiert hatte. Eine ausführliche Diskussion mit Beispielen und Vergleich findet sich gegen Ende dieses Threads.
Zuletzt geändert von CodingCat am 12.09.2011, 12:08, insgesamt 3-mal geändert.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Bei den zwei, drei Objekten die eine Referenz auf das Log brauchen sowas von egal...
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Und das is sinnvoll?CodingCat hat geschrieben:Nachtrag zum Post untendrunter: Bei mir loggen aber praktisch alle Objekte.
Ich denk mehr muss man dazu nichtmehr sagen :PCodingCat hat geschrieben:Ich kann es ja ab sofort "globales Singleton" nennen, ein gänzlich neues und innovatives Entwurfsmuster, welches das klassische Singleton mit der klassischen globalen Variable verbindet. :mrgreen:
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Was soll daran nicht sinnvoll sein? Ich hasse es, wenn Fehler auftreten, ohne dass ich was davon mitbekomme. Ich logge sogar jede Exception noch bevor sie fliegt. ;-) Aber oftmals will man eben keine Exception, und trotzdem was vom Fehler mitbekommen - was bei nicht behandelten Rückgabewerten sonst ja eher die Ausnahme wäre.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Für sowas verwend ich einen Debugger. Ein Log verwend ich für grobe Diagnose wenn beim Kunden was schiefläuft wo ich nicht direkt Debuggen kann. Da kommen so Sachen rein wie irgendwelche Fehler beim Laden oder was für eine Hardwarekonfiguration der Rechner hat und welche Versionen einzelner Komponenten verwendet werden und das hat mir schon viel Schmerz erspart. Aber alles und überall zu loggen hat sich für mich noch nie als sinnvoll herausgestellt...
assert() ;)CodingCat hat geschrieben:Aber oftmals will man eben keine Exception, und trotzdem was vom Fehler mitbekommen.
Zuletzt geändert von dot am 01.06.2011, 15:42, insgesamt 1-mal geändert.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Naja, das kommt halt sehr auf das Projekt und seine Größe an - mit dem Debugger kriege ich eben doch mehr das mit, was ich mir gerade gezielt ansehe, und lang nicht alles, was gerade schief laufen könnte. Und das Logging kostet mich praktisch nichts, warum also nicht das Maximum an Information mitnehmen. Ja, assert nutze ich auch. Aber nicht für Fehler, die sich prinzipiell ignorieren lassen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Weil die wirklich wichtige Information dann im Rest untergeht.CodingCat hat geschrieben:Und das Logging kostet mich praktisch nichts, warum also nicht das Maximum an Information mitnehmen.
Gut, die Art von Fehler hatte ich wohl noch nie ;)CodingCat hat geschrieben:Ja, assert nutze ich auch. Aber nicht für Fehler, die sich prinzipiell ignorieren lassen.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Wow, heute komme ich noch zu meinem absoluten Post-Rekord. :P
Ich glaube du verstehst mich falsch, ich logge nicht alles was passiert, sondern alles was schief geht, das ist in der Regel nichts. ;-)Weil die wirklich wichtige Information dann im Rest untergeht.
Du Glücklicher. :)Gut, die Art von Fehler hatte ich wohl noch nie.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- Krishty
- Establishment
- Beiträge: 8375
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Ein Log ist doch nicht nur für den einen tödlichen Fehler da, der das Programm abschießt, sondern um nachvollziehen zu können, wie es dazu kam. Das Problem am Debugger ist, dass man nur den aktuellen Zustand sieht und alles zuvor geschehene verloren ist. Wenn im Programm erstmal vollkommen andere Daten sind als man für den Lauf erwartet hätte (was ja nicht heißt, dass sie beim Laden ungültig waren oder man den Fehler anderweitig früher hätte erkennen können!) und man nicht geloggt hat, dass das System seine ganzen Caches erneuert hat und komplett andere Daten durchgegangen ist als es sollte weil man einen falschen Login eingetippt hat, kann man die gesamte Ausführung im Debugger durchsteppen. Je größer die Fehlertoleranz eines Systems (die eine Anforderung sein kann!), desto schlimmer wird es.
Auf ein Log kann ich, und imo jeder, genauso wenig verzichten wie auf Ausnahmen oder assert. Es gibt halt nicht den Fehler an sich, von dem ihr hier redet. In Flugzeugen verzichtet man auch nicht mit dem Verweis auf die hohe Zuverlässigkeit und Testabdeckung auf die Black Box (oder nimmt damit nur den Start auf „damit keine wirklich wichtige Information im Rest untergeht“).
Auf ein Log kann ich, und imo jeder, genauso wenig verzichten wie auf Ausnahmen oder assert. Es gibt halt nicht den Fehler an sich, von dem ihr hier redet. In Flugzeugen verzichtet man auch nicht mit dem Verweis auf die hohe Zuverlässigkeit und Testabdeckung auf die Black Box (oder nimmt damit nur den Start auf „damit keine wirklich wichtige Information im Rest untergeht“).
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Schon klar, aber ich hatte noch nie soviele Objekte die etwas loggen müssen dass eine globale Variable für das Log notwendig geworden wäre um den Speicherverbrauch durch die Dependency Injection zu sparen oO
Es ist jedenfalls sicherlich nicht so dass jedes einzelne kleine Sprite was loggen muss. Wenn dann vielleicht die Klasse die die Sprites erzeugt...
Es ist jedenfalls sicherlich nicht so dass jedes einzelne kleine Sprite was loggen muss. Wenn dann vielleicht die Klasse die die Sprites erzeugt...
Zuletzt geändert von dot am 01.06.2011, 16:33, insgesamt 1-mal geändert.
- Krishty
- Establishment
- Beiträge: 8375
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Ich ganz persönlich hatte auch noch nie so viele unterschiedliche Logs, dass ich mehr als eine globale Variable bzw. Funktion gebraucht hätte. (Jetzt dürft ihr mich stiefeln)
Halt jedem das Seine, oder jeder das Ihrige, oder allen das Essig.
Halt jedem das Seine, oder jeder das Ihrige, oder allen das Essig.
Imo muss man Fehler loggen, sobald sie auftreten. Das bedeutet, dass jede Ausnahme beim Werfen eine Referenz auf den Logger braucht. Kann also bei der Sprite was schiefgehen, braucht sie ihn meiner Einschätzung nach durchaus.dot hat geschrieben:Es ist jedenfalls sicherlich nicht so dass jedes einzelne kleine Sprite was loggen muss. Wenn dann vielleicht die Klasse die die Sprites erzeugt...
Zuletzt geändert von Krishty am 01.06.2011, 16:34, insgesamt 1-mal geändert.
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Gut, dann ist aber eine globale Variable ausreichend, ein Singleton wäre imo falsch. Der einzige wirkliche Anwendungsfall der mir bisher je untergekommen ist wo ein Singleton evtl. sinnvoll sein könnte ist ein Scheduler in einem Betriebssystem. Bei dem ist es evtl. wirklich eine wesentliche Eigenschaft des Typs dass nur genau eine Instanz existieren darf. Aber selbst da wär ich persönlich sehr skeptisch und würd vermutlich eher kein Singleton verwenden.Krishty hat geschrieben:Ich ganz persönlich hatte auch noch nie so viele unterschiedliche Logs, dass ich mehr als eine globale Variable bzw. Funktion gebraucht hätte.
Zuletzt geändert von dot am 01.06.2011, 16:41, insgesamt 1-mal geändert.
- Krishty
- Establishment
- Beiträge: 8375
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Die Sache hat aber auch ein Haken: Und das ist C++’ völlig bescheuerte undefinierte statische Initialisierungsreihenfolge. Du kannst darum keine anderen globalen Variablen mehr bei ihrer Initialisierung was loggen lassen – in eine Funktion verpackt hingegen hat man einen eindeutigen Initialisierungszeitpunkt (den Augenblick, in dem es zuerst gebraucht wird).dot hat geschrieben:Gut, dann ist aber eine globale Variable ausreichend, ein Singleton wäre imo einfach nur falsch.
Ob man dann ein Singleton hat oder nicht hängt dann nurnoch davon ab, ob diese Funktion innerhalb oder außerhalb der Klasse liegt. Für mich eine Formfrage. Darum ist das Singleton auch meines Ermessens nach nicht pauschal falsch.
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Ok, das ist zugegeben ein Argument. Allerdings hat man dieses Problem mit Dependency Injection schon rein prinzipell nicht da der Fall dort systematisch bedingt nie eintreten kann. Und daher würde ich letzeres als die definitiv bessere Lösung ansehen.Krishty hat geschrieben:Die Sache hat aber auch ein Haken: Und das ist C++’ völlig bescheuerte undefinierte statische Initialisierungsreihenfolge. Du kannst darum keine anderen globalen Variablen mehr bei ihrer Initialisierung was loggen lassen – in eine Funktion verpackt hingegen hat man einen eindeutigen Initialisierungszeitpunkt (den Augenblick, in dem es zuerst gebraucht wird).
- Krishty
- Establishment
- Beiträge: 8375
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Wo wir gerade bei Objektorientierungsgrundsätzen sind: Ich für meinen Teil überlege schon lange, ob ich Logging überhaupt objektorientiert handhaben soll und nicht etwa funktional – ich empfinde den Logger mehr und mehr als Gespenst von etwas völlig Funktionalem, was ich nur extrem verkompliziere. Wenn tatsächlich irgendwer loggt, ist das imo eine Handlung meines kompletten Prozesses, also … riecht das nach globaler Funktion.dot hat geschrieben:Allerdings hat man dieses Problem mit Dependency Injection schon rein prinzipell nicht da der Fall dort systematisch bedingt nie eintreten kann.
Zurückgehalten werde ich nur von der Leistung und der Überschaubarkeit der Syntax (log << blubb << "foo"; ist halt eleganter und schneller als log(toString("blubb") + "foo")).
Einfach mal neben die Tüte gekotzt.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Ja, bzgl. globalem Zugriff habe ich Krishty nichts mehr hinzuzufügen. Um nochmal auf das Singleton zurückzukommen, hier hatten wir uns ja schon auf Seite 2 geeinigt, dass ich Singleton im Eingangspost zum Thema Logging zu sehr mit globalem Zugriff vermengt hatte. Die Ursache hierfür, das C++-Singleton-typische Muster der lokal definierten statischen Variable, hat Krishty eben auch schon genannt. Tatsächlich nutze ich zum Logging sogar eine statische Instanz, die lokal in einer freien Funktion definiert ist, ohne dass die Anzahl der konstruierbaren Instanzen prinzipiell beschränkt ist.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Ja, das ist eine gute Frage. Logging ist so eine Sache wo ich auch noch keine wirklich zufriedenstellende Lösung gefunden hab. Ein Log ist sicherlich einer der extrem seltenen Fälle wo man wirklich für ein Singleton oder eine globale Variable argumentieren kann (das wohl beste Argument hast du ja oben gebracht) und ich will ja nicht Cat's Lösung runtermachen oder so. Ich find nur Singleton rein prinzipiell so hässlich dass ich in dem Kontext gern immer ein wenig übertreib, ich persönlich würds, was auch immer passiert, einfach nie tun ;)
Für sehr einfache Dinge verwend ich evtl. einfach einen globalen std::ofstream log("log.txt") und fertig. Streams sind halt sehr angenehm. Logging ist auch eine der wenigen Sachen wo ich mich evtl. für den Einsatz von Makros erwärmen kann da automatisches Mitloggen von File und Zeile eben doch angenehm ist. Man kann sich natürlich alles Mögliche einfallen lassen, wie wärs z.B. mit sowas:
Ein Makro log() dass eine entsprechende Funktion mit __FILE__ und __LINE__ aufruft die vielleicht für die verschiedenen Typen ERROR() und WARNING() überladen ist die selbst eben jeweils Streamoperationen unterstützen.
Oder einfach:
Das ließe sich direkt in eine Ausgabe auf einen Stream übersetzen. Prinzipiell fallen mir da alle 5 min. neue Möglichkeiten ein^^
Für sehr einfache Dinge verwend ich evtl. einfach einen globalen std::ofstream log("log.txt") und fertig. Streams sind halt sehr angenehm. Logging ist auch eine der wenigen Sachen wo ich mich evtl. für den Einsatz von Makros erwärmen kann da automatisches Mitloggen von File und Zeile eben doch angenehm ist. Man kann sich natürlich alles Mögliche einfallen lassen, wie wärs z.B. mit sowas:
Code: Alles auswählen
log(ERROR() << "foo " << 42);
Oder einfach:
Code: Alles auswählen
log << ERROR("foo " << 42);
Zuletzt geändert von dot am 01.06.2011, 17:17, insgesamt 1-mal geändert.
- Chromanoid
- Moderator
- Beiträge: 4307
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: [C++] Speicherfreigabe bei statischem Singleton
MMh habt ihr schon mal gesehen was man mit Log4J bzw. java.util.logging und so machen kann? Die Komplexität von Logging sollte man nicht unterschätzen. Man sollte z.B. in der lage sein, pro Modul bzw. Klasse in unterschiedliche Logs zu schreiben ohne das im Code angeben zu müssen. Z.B. kann es im Produktiv-Betrieb sinnvoll sein, Meldungen eines bestimmten Moduls bestimmter Warnstufe per Email zu versenden etc. Das Ausgabeformat sollte auch konfigurierbar sein XML, HTML, TXT usw. Es gibt sowas wie log4j bestimmt auch für C++.
Zuletzt geändert von Chromanoid am 01.06.2011, 17:20, insgesamt 1-mal geändert.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Ja, hier sind Makros ausnahmsweise wirklich Gold wert, __LINE__ und __FILE__ machen das Leben einfach enorm leichter. Der globale std::ofstream ist halt wieder extrem problematisch in Bezug auf Initialisierungsreihenfolge. Deshalb ist das für mich keine Alternative zur lokal definierten statischen Variable, Singleton muss ja deshalb nicht (und sollte womöglich auch, wie eben angemerkt, nicht) sein.
Den Vorteil gegenüber (mehreren) globalen Funktionen sehe ich darin, dass der immer notwendige zentrale Zugriffspunkt auf das Bezugsobjekt automatisch dafür sorgt, dass dieses Objekt dort auch tatsächlich erzeugt wird. Bei mehreren Overloads einer globalen Funktion müsste derartiges Verhalten schon wieder in alle Funktionen kopiert werden.
Nachtrag: Krishty merkte gerade an, dass am Ende immer Buchstaben ausgegeben werden müssen, und die entsprechende zugrundeliegende Funktion dann problemlos die Initialisierung übernehmen kann.
Nachtrag: Krishty merkte gerade an, dass am Ende immer Buchstaben ausgegeben werden müssen, und die entsprechende zugrundeliegende Funktion dann problemlos die Initialisierung übernehmen kann.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- Brainsmith
- Establishment
- Beiträge: 109
- Registriert: 04.09.2009, 13:52
- Echter Name: Fabbo
Re: [C++] Speicherfreigabe bei statischem Singleton
Huch, hab mich ganz schön erschreckt, als ich hier reingeschaut hab.. So viele neue Posts.
Also.. Das Makro benutze ich auch nicht. Ich habe das nur geschrieben, um klarzumachen, wie der Singleton definiert ist. Und nun mal eine andere Frage:
Ich habe das Gefühl, dass hier mehrere Leute Singletons nicht mögen. Warum ist das so?
In meinem Falle geht es um eine Sound Engine. Ich will halt nicht, dass jemand versucht, das Ding zweimal zu initialisieren.
Wo wir aber gerade dabei sind. Gibt es Performance-Nachteile bei nem statischen Singleton? Das wäre für mich das einzige Argument, was zählt.
Also.. Das Makro benutze ich auch nicht. Ich habe das nur geschrieben, um klarzumachen, wie der Singleton definiert ist. Und nun mal eine andere Frage:
Ich habe das Gefühl, dass hier mehrere Leute Singletons nicht mögen. Warum ist das so?
In meinem Falle geht es um eine Sound Engine. Ich will halt nicht, dass jemand versucht, das Ding zweimal zu initialisieren.
Wo wir aber gerade dabei sind. Gibt es Performance-Nachteile bei nem statischen Singleton? Das wäre für mich das einzige Argument, was zählt.
- Schrompf
- Moderator
- Beiträge: 5237
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Und wem bitte soll das "aus Versehen" passieren? Mal ganz davon abgesehen, dass auf allen aktuellen Betriebssystemen zwei parallele Sound Engines stressfrei möglich sind.Brainsmith hat geschrieben: Ich habe das Gefühl, dass hier mehrere Leute Singletons nicht mögen. Warum ist das so?
In meinem Falle geht es um eine Sound Engine. Ich will halt nicht, dass jemand versucht, das Ding zweimal zu initialisieren.
Zum Thema "nicht mögen": ich kann nicht für die anderen sprechen, aber ich persönlich habe schon mehrmals Singletons wieder entfernen müssen, weil der "Zu aller Zeit nur diese eine Instanz" einem halt immer irgendwann auf die Füße fallen wird. Und aus heutiger Sicht kann ich nur noch den Kopf schütteln, wenn Leute extra Arbeit und Code auf eine Aufgabe verschwenden, um einen ernsthaften Designfehler in ihrer Softwarearchitektur festzunageln. Wenn es momentan schön bequem ist, eine globale Instanz zu haben, na dann sollen sie halt eine anlegen.
Singletons würde ich nur in dem Fall benutzen, wo der Konstruktor nach Bedarf beim ersten Aufruf laufen soll, ohne dass ich mit normalem Code vorher was einrichten kann.
Ja, es kostet bei jedem get() die Rechenzeit, auf Existenz der Instanz zu prüfen, um sie notfalls anlegen zu können. Bei einer "static" Instanz erzeugt der Compiler diesen Code für Dich, aber die Rechenzeit ist dieselbe. Wenig, aber nicht Null.Wo wir aber gerade dabei sind. Gibt es Performance-Nachteile bei nem statischen Singleton? Das wäre für mich das einzige Argument, was zählt.
Zuletzt geändert von Schrompf am 02.06.2011, 12:48, insgesamt 1-mal geändert.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- Krishty
- Establishment
- Beiträge: 8375
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Dann triffst du höchstwahrscheinlich alle deine Entwurfsentscheidungen auf völlig verkehrter Grundlage.Brainsmith hat geschrieben:Gibt es Performance-Nachteile bei nem statischen Singleton? Das wäre für mich das einzige Argument, was zählt.
Was das Singleton an sich angeht: Wenn du eine globale Abhängigkeit hast, ändert sich daran auch nichts, wenn du sie in einer Funktion verpackst. Du machst dir nur ein bisschen mehr Arbeit, aber die ist Verschwendung weil die Abhängigkeit an sich bleibt. Was jedoch wiederum dafür spricht ist, wie erwähnt, die undefinierte Initialisierungsreihenfolge bei globalen Instanzen.
- Brainsmith
- Establishment
- Beiträge: 109
- Registriert: 04.09.2009, 13:52
- Echter Name: Fabbo
Re: [C++] Speicherfreigabe bei statischem Singleton
Man muss immer vom dümmsten User ausgehen, den man sich denken kann. =DSchrompf hat geschrieben:Und wem bitte soll das "aus Versehen" passieren? Mal ganz davon abgesehen, dass auf allen aktuellen Betriebssystemen zwei parallele Sound Engines stressfrei möglich sind.Brainsmith hat geschrieben: Ich habe das Gefühl, dass hier mehrere Leute Singletons nicht mögen. Warum ist das so?
In meinem Falle geht es um eine Sound Engine. Ich will halt nicht, dass jemand versucht, das Ding zweimal zu initialisieren.
Hmm.. da habeich wohl etwas falsch verstanden. Ich dachte, wenn der Singleton statisch ist, wird der direkt zu Beginn auf den Stack gelegt und dann einfach nur imemr wieder geholt, falls notwendig.Ja, es kostet bei jedem get() die Rechenzeit, auf Existenz der Instanz zu prüfen, um sie notfalls anlegen zu können. Bei einer "static" Instanz erzeugt der Compiler diesen Code für Dich, aber die Rechenzeit ist dieselbe. Wenig, aber nicht Null.Wo wir aber gerade dabei sind. Gibt es Performance-Nachteile bei nem statischen Singleton? Das wäre für mich das einzige Argument, was zählt.
In dem Fall ist es aber immernoch Meckern auf hohem Niveau. Wie oft greift man schon per GetInstance darauf zu? Im Regelfall passiert das dann auch nicht zur Laufzeit, sondern zur Ladezeit. Da kann ich die paar Abfragen noch verkraften.
Okay, ich bin ja lernbereit. Bitte kläre mich auf. Ich sehe den Punkt einfach nicht. Das, was zählt, ist Performance. Dabei ist es mir bisher völlig egal gewesen, ob etwas mal nicht objektorientiert war oder ob der Code für andere nicht leserlich ist. Dafür gibts ja auch Kommentare. Und schlechter wartbar ist der Code dadurch auch nicht. Also wäre es nett, wenn du da ein wenig ins Details gehen könntest.Krishty hat geschrieben:Dann triffst du höchstwahrscheinlich alle deine Entwurfsentscheidungen auf völlig verkehrter Grundlage.Brainsmith hat geschrieben:Gibt es Performance-Nachteile bei nem statischen Singleton? Das wäre für mich das einzige Argument, was zählt.
Ps: Der letzte Teil hört sich evtl ein wenig zickig an. Ist nicht so gemeint. Ich meine das schon ernst, was ich da schreibe. =D
- Krishty
- Establishment
- Beiträge: 8375
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Es gibt generell nur einen Punkt, wo Leistung ein Entscheidungskriterium ist: Nämlich, wenn du einen Algorithmus für die Lösung deines Problems aussuchst; und dann ist die Leistung in Laufzeitverhalten zu bewerten. Ansonsten geht es fast immer darum, das Problem so einfach wie möglich (so wenig komplex wie möglich, mit so wenig Quelltext wie möglich, mit so wenig Aufwand wie möglich) zu lösen. Einen Algorithmus zu wählen, der dein Problem in O(n×log(n)) löst statt in O(n²) wird dir mehr Leistung bringen als alle anderen Optimierungen, die du unter Einbußen von Wartbarkeit, Lesbarkeit und – vor allem – Zeit jemals zusammenschaben kannst, zusammen.Brainsmith hat geschrieben:Okay, ich bin ja lernbereit. Bitte kläre mich auf. Ich sehe den Punkt einfach nicht. Das, was zählt, ist Performance. Dabei ist es mir bisher völlig egal gewesen, ob etwas mal nicht objektorientiert war oder ob der Code für andere nicht leserlich ist. Dafür gibts ja auch Kommentare. Und schlechter wartbar ist der Code dadurch auch nicht. Also wäre es nett, wenn du da ein wenig ins Details gehen könntest.
Ps: Der letzte Teil hört sich evtl ein wenig zickig an. Ist nicht so gemeint. Ich meine das schon ernst, was ich da schreibe. =D
Und wenn es dann doch noch zu langsam ist, dann nicht wegen irgendeinem Singleton sondern wegen dem einen Prozent deines Quelltexts, der die innerste Schleife ausmacht. Den kannst du dann oft immernoch optimieren ohne den Rest kaputtzumachen. Oft ist es dann aber auch so, dass die simpelste Lösung am schnellsten abgearbeitet wird.
Ist natürlich nur eine Faustregel. Wenn man im Embedded-Bereich Pixel zusammenschabt oder auf der GPU hunderte Recheneinheiten füttern muss, verhält sich das u.U. kontraintuitiv (weil das übliche Bild vom Laufzeitverhalten durch Speicherlatenzen, Branching oder Flaschenhälse bei bestimmten Vorgängen verzerrt wird – oder weil die Compiler einen feuchten Kehricht wert sind). Wenn du aber bei einem normalen PC-Spiel alle deine Entscheidungen zeilenmäßig nach Leistung fällst, steuerst du langfristig auf eine Katastrophe zu.
- Brainsmith
- Establishment
- Beiträge: 109
- Registriert: 04.09.2009, 13:52
- Echter Name: Fabbo
Re: [C++] Speicherfreigabe bei statischem Singleton
Krishty hat geschrieben:Es gibt generell nur einen Punkt, wo Leistung ein Entscheidungskriterium ist: Nämlich, wenn du einen Algorithmus für die Lösung deines Problems aussuchst; und dann ist die Leistung in Laufzeitverhalten zu bewerten. Ansonsten geht es fast immer darum, das Problem so einfach wie möglich (so wenig komplex wie möglich, mit so wenig Quelltext wie möglich, mit so wenig Aufwand wie möglich) zu lösen. Einen Algorithmus zu wählen, der dein Problem in O(n×log(n)) löst statt in O(n²) wird dir mehr Leistung bringen als alle anderen Optimierungen, die du unter Einbußen von Wartbarkeit, Lesbarkeit und – vor allem – Zeit jemals zusammenschaben kannst, zusammen.Brainsmith hat geschrieben:Okay, ich bin ja lernbereit. Bitte kläre mich auf. Ich sehe den Punkt einfach nicht. Das, was zählt, ist Performance. Dabei ist es mir bisher völlig egal gewesen, ob etwas mal nicht objektorientiert war oder ob der Code für andere nicht leserlich ist. Dafür gibts ja auch Kommentare. Und schlechter wartbar ist der Code dadurch auch nicht. Also wäre es nett, wenn du da ein wenig ins Details gehen könntest.
Ps: Der letzte Teil hört sich evtl ein wenig zickig an. Ist nicht so gemeint. Ich meine das schon ernst, was ich da schreibe. =D
Und wenn es dann doch noch zu langsam ist, dann nicht wegen irgendeinem Singleton sondern wegen dem einen Prozent deines Quelltexts, der die innerste Schleife ausmacht. Den kannst du dann oft immernoch optimieren ohne den Rest kaputtzumachen. Oft ist es dann aber auch so, dass die simpelste Lösung am schnellsten abgearbeitet wird.
Ist natürlich nur eine Faustregel. Wenn man im Embedded-Bereich Pixel zusammenschabt oder auf der GPU hunderte Recheneinheiten füttern muss, verhält sich das u.U. kontraintuitiv (weil das übliche Bild vom Laufzeitverhalten durch Speicherlatenzen, Branching oder Flaschenhälse bei bestimmten Vorgängen verzerrt wird – oder weil die Compiler einen feuchten Kehricht wert sind). Wenn du aber bei einem normalen PC-Spiel alle deine Entscheidungen nach Leistung fällst, steuerst du langfristig auf eine Katastrophe zu.
Ich hab mich vielleicht etwas drastisch ausgedrückt. Natürlich ist Wartbarkeit ein Kriterium, wie auch die Geschwindigkeit, in der der Code geschrieben wird. Bei einem Singleton hält sich das natürlich auch in Grenzen.
Ich glaube aber, ich habe den Punkt gefunden, wo unsere Meinungen differieren:
Die Sache ist dann doch eher, was man als Problem definiert. Ich sehe es meist so, dass alles, was ich programmiere in gewisser Weise ein Problem ist, weshalb diese Regel auch fast immer greift. Andererseits ist mir natürlich auch bewusst, was du meinst (Optimieren am falschen Ende vermeiden). Eine Frage ist aber auch: Was ist angenehmer: Im Nachhinein nochmal über den Code zu schauen und Optimierungen vorzunehmen oder den Code direkt so zu schreiben, dass solche Schritte unnötig sind. Dadurch ergibt sich mir dann die Folgefrage, welche Methode letztendlich schneller ist, wenn man die jeweilge Methde gwöhnt ist.Es gibt generell nur einen Punkt, wo Leistung ein Entscheidungskriterium ist: Nämlich, wenn du einen Algorithmus für die Lösung deines Problems aussuchst
Scheinbar wird es als Axiom angesehen, dass der eine Workflow besser ist, als der andere. Falls jemand einen repräsentativen Artikel zum Thema hat, wäre ich sehr dankbar. Nur weil ein Ansatz für viele gilt, bedeutet dies nicht automatisch, dass er für alle richtig ist.
Zusätzlich dazu fühle ich mich immer furchtbar, wenn ich Code geschrieben habe, von dem ich weiß, dass er schneller sein könnte. Da möchte ich am liebsten wild mit einem Auge zucken und alles neu schreiben. :D
Naja, ich treffe die Entscheidungen natürlich nicht zeilenmäßig, sondern problemmäßig nach Leistung (natürlich nur nach meinem doch recht.. sagen wir mal beschränkten Wissen).Wenn du aber bei einem normalen PC-Spiel alle deine Entscheidungen zeilenmäßig nach Leistung fällst, steuerst du langfristig auf eine Katastrophe zu.
Und tatsächlich gibt es auch Plattformen, wo man absolut effizient programmieren muss, wie zum Beispiel den Nintendo DS, wenn man da was rausholen will.
Ich habe mit dieser Einstellung in zwei kommerziellen Projekten gearbeitet und keine Probleme damit gehabt. Weder zeitlich, noch hat jemand die Lesbarkeit meines Codes bemängelt.
ich schließe natürlich die Möglichkeit nicht aus, dass wir gnadenlos aneinander vorbei schreiben und wir zB Sachen wie Lesbarkeit, Wartbarkeit etc. unterschiedlich definieren. Zumindest der Lesbarkeitsbegriff ist doch eher schwammig.
- dot
- Establishment
- Beiträge: 1748
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [C++] Speicherfreigabe bei statischem Singleton
Auf der einen Seite argumentierst du dass für dich nur rohe Performance zählt, auf der anderen Seite hast du bei einer typischen Implementierung des Singleton Pattern (z.B. Meyers Singleton) wie Schrompf schon sagte bei jedem Zugriff auf den Singleton infolge der statischen Variable mit gewissem Overhead zu rechnen (der Compiler muss ja Code einbaun der checked ob die Variable schon initialisiert wurde). Und dabei ist das Ding noch nichtmal annähernd Thread-Safe.
Wie schon gesagt: Das Hauptproblem von Singleton ist dass es praktisch immer für eine globale Instanz missbraucht wird. Manche nennen es sogar eine "objektorientierte Lösung für eine globale Variable" und solche Dinge, als ob es durch eine nette Verpackung besser würde. Genau dafür war Singleton per Definition nie gedacht. Ich hab sicher schon hunderte Singletons gesehn und jedes einzelne davon war ein grober Designfehler, was tut man nicht alles für etwas vermeintliche Bequemlichkeit? Singleton verschleiert Abhängigkeiten. Aber nur weil du sie nicht siehst heißt das noch lange nicht dass sie nicht da sind. Sogar rein theoretische Beispiele für den korrekten Einsatz von Singleton sind extrem rar und selbst dort findet man praktisch immer genug Gegenargumente und bessere Alternativen.
Singletons sind wie Krebs: Wenn du merkst dass du sie hast ist es meistens schon zu spät, denn das Singleton hat bereits überall in deinen Code metastasiert.
Wie schon gesagt: Das Hauptproblem von Singleton ist dass es praktisch immer für eine globale Instanz missbraucht wird. Manche nennen es sogar eine "objektorientierte Lösung für eine globale Variable" und solche Dinge, als ob es durch eine nette Verpackung besser würde. Genau dafür war Singleton per Definition nie gedacht. Ich hab sicher schon hunderte Singletons gesehn und jedes einzelne davon war ein grober Designfehler, was tut man nicht alles für etwas vermeintliche Bequemlichkeit? Singleton verschleiert Abhängigkeiten. Aber nur weil du sie nicht siehst heißt das noch lange nicht dass sie nicht da sind. Sogar rein theoretische Beispiele für den korrekten Einsatz von Singleton sind extrem rar und selbst dort findet man praktisch immer genug Gegenargumente und bessere Alternativen.
Singletons sind wie Krebs: Wenn du merkst dass du sie hast ist es meistens schon zu spät, denn das Singleton hat bereits überall in deinen Code metastasiert.