Bücher zu C++ und OOA/D/P von Stroustrup, Booch, Gamma et al. und anderen



  • Bjarne Stroustrup - "Die C++ Programmiersprache"
    4.Auflage Addison-Wesley 2000 ( aka. "Special Edition" - also mit dem STL Referenzteil )
    ca. 1100 Seiten
    ca. EUR 50,--

    Bjarne Stroustrup http://www.research.att.com/~bs/ hat die Sprache erfunden und ihre Entwicklung massgeblich beinflusst.

    Sein Buch ist imo schwierig zu "lesen" - bei vielen Abschnitten stelte sich mir immer wieder die Frage "Wozu muss ich das eigentlich so genau wissen?"

    Andererseits ist das Buch imo hervorragend zum Nachschlagen ( auch und gerade zur STL ) geeeignet - es gab bislang ( in ca. 10 Jahren ) keine Frage zu C++ deren Lösung sich nicht irgendwo in den 1100 Seiten ( resp. der Vorgängerausgabe gefunden hätte!

    Imo lernt man eine Sprache sowieso nur "by doing" - und dafür ist das Buch genau richtig!

    Am Ende jedes Kapitels gibt der Verfasser Ratschläge.
    Man kann ziemlich sicher sein dass deren Nichtbefolgung Probleme nach sich zieht... 😉

    Professor Stroustrup stellt im Anhang jedes kapitels nette "kleine" Aufgaben an seine Leser deren Bearbeitungszeit ( nach seiner Schätzung ) zwischen 10 Minuten und einem ganzen Tag betragen kann.

    Für die Aufgaben gibt's imo einen Band mit Lösungen das ich mal gesehen hab aber gerade nicht im Netz finde.

    Wenn man die alle gelöst und seine Lösungen verifiziert hat kann man wohl von sich mit gutem Gewissen behaupten C++ zu beherrschen.

    Imho ein geniales Buch von einem genialen Autor und Programmierer.
    Ohne das Buch in Griffweite zu haben arbeite ich nicht nmit C++, das Buch wird nicht verliehen und ich werd nervös wenn Besucher auch nur darin zu blättern beginnen 😉

    Grüsse

    Gast++



  • Ich hab das Buch und ich habs auch mal großteils gelesen, aber zum Nachschlagen benutze ich es sehr selten. Ich finde google liefert mir da schneller die passende msdn/sgi/rogueweave Doku-Seite(n).

    Pflichtlektüre sind wohl (More) Effective C++ und (More) Exceptional C++. Für Fortgeschrittene dann Modern C++ Design und C++ Templates - The Complete Guide.

    Effective STL find ich noch ganz interressant.



  • Grady Booch "Objektorientierte Analyse und Design"
    2. Korrigierter Nachdruck Addison-Wesley 1996
    ca. 720 Seiten
    ca. EUR 50,00

    Grady Booch http://en.wikipedia.org/wiki/Grady_Booch ist einer der Urheber der Objektorientierten Methode. Von ihm stammt die sogenannte "Booch-Notation"( die mit den "Wölkchen" ).

    Nachfolger der Notation ist die von ihm mitentwickelte "Unified Modelling Language" (UML) die heute als Standard gilt.

    In dem Buch das mir vorliegt wird die Booch-Notation verwandt, ob dies bei neueren Ausgaben anders ist entzieht sich meiner Kenntnis.
    Die Notation wird im im Einband definiert.

    Das Buch gliedert sich in drei Teile

    - Konzepte
    - Methode
    - Appliakationen

    und einen Anhang indem die OO-Featuress populärer Programmiersprachen, auch von C++, aufglistet sind.

    Für Code-Beispiele verwendet Booch C++.

    Das ist imho ein "Lese"-Buch. OO wurde im letzten Jahrzehnt derart "ge-hyped" dass es imho sehr klärend ist ein Werk aus einer Zeit zu lesen als es Autoren auch noch darum ging dem "neuen" Programmierparadigma zum Durchbruch zu verhelfen.

    Grady Booch ist ein weltweit renommierter Dozent und die Begabung sein Publikum zu unterhalten findet auch in diesem Werk seinen Ausdruck.

    Booch kann Zusammenhänge plastisch erläutern und trotzdem eine effiziente Abstration finden.

    Ein Beispiel:

    Mit Metaklassen hatte ich bis zur Beschäftigung mit Python nie etwas zu tun gehabt ( CLOS und Smalltalk mag ich einfach nicht )

    Booch schafft es auf zwei(!) Seiten und mit einer Graphik seinem Leser das Konzept soweit zu motivieren und einen Überblick zu geben das ich dennoch immer das Gefühl hatte das Konzept hinreichend zu kennen und den verwandten Mechanismus generischer Programmierung ( aka "Templates" ) einordnen zu können.
    Zwar bin ich kein Java-Fan aber mir war immer ziemlich klar dass Java solch ein Mechnismus ( oder halt mehr "Meta" als nur Class ) fehlte. Interessantr weise deckt sich das was ich nun über Generics lese oft mit dem was ich mir nach der Lektüre von Booch's Werk selbst zusammengereimt hatte.

    Booch stellt vielfach Überlegungen zur Verbindung von Methoden und Werkzeugen an; man gewinnt dadurh einen neuen Blickwinkel für seine Arbeit.

    Wenn ich ein Projekt betrachte könnt eich nicht sagen "dies oder jenes habe ich so gelöst weil ich das Buch gelesen habe". Aber wenn ich's mal wieder aufschlage stelle ich fest dass das offenabr doch so ist. 😉

    Imho unentbehrlich und unterhaltsam.
    Reitzt zum Mitmachen und Weiterführen.

    Grüsse

    Gast++



  • Gamma, Helm, Johnson, Vlissides
    Entwurfsmuster
    Elemente wiederverwendbarer objektorientierter Software
    4. korrigierter Nachdruck Addison Wesley 1996
    ca. 480 Seiten
    ca. EUR 50,00

    Die "Gang of Four"(aka "GoF"), beim Artikel zu ihrem Werk zu finden http://en.wikipedia.org/wiki/Design_Patterns,
    und ihr Werk sind "Grale" der Softwaretechnik.

    Dies Buch hat einen solch immensen Einfluss auf Sprachen, Bibliotheken, ganze Entwicklungssysteme gehabt, dass die heutige Softwarelandschaft ohne dies schwer vorstellbar ist.

    Das Buch gleidert sich in drei Teile:

    - Einführung
    - Fallbeispiel - ein Dokumenteneditor
    - Musterkatalog,

    letzterer unterteilt in 5 Erzeugungsmuster (z.B. "Singleton"), 7 Strukturmuster ( z.B. "Proxy" ) und 11 Verhaltensmuster ( z.B. "Schablonenmethode" ).

    Verwandt wird die OMT-Notation, die sich aber mit UML-Kennntnissen ohne weiteres lesen laßt. Codebeispiele sind meist in C++ formuliert.

    im Einband findet sich ein Übersicht über die Notation un den Musterkatalog.

    Jedes Muster wird mit einem konkreten Beispiel mit einm Diagramm und einer Abtraktion, ebenfalls wieder mit einem Diagramm, erläutert.
    Pro und Contra des Musters werden schnökellos dargestellt.

    Wenn man die Dokumentation zu Programmbibliotheken und Frameworks liest wird man häufig auf die Begrifflichkeit der GoF stossen ohne dass diese noch extra erklärt wird oder die Quelle genannt.
    Meines Erachtens liegt dies daran dass viele Entwickler die solch komplexe Software schreiben, die Begrifflichkeit schon soweit verinnerlicht haben dass es ihnen in Fleisch und Blut übergegangen ist.

    Nachdem man sich mit dem Buch vetraut gemacht hat, kann man imo mit jeder OO-Programiersprache, egal wie genau man sie vorher kannte, effizienter umgehen.

    Die GoF legt sehr grossen Wert auf "Schnittstellen-Vererbung" ( Gegensatz: "Implementierungsvererbung") und verwendet sehr häufig eine abstrakte Basisklasse die Clienten einen Zugriffspunkt bereitstellt.

    Die Methodik ( obwohl nicht als extra "Muster" aufgenommen ) findet sich in unzähligen Bibliotheken und Frameworks wieder.

    Allerdings ist dieses Buch nicht gerade enfach zu lesen; es ist sehr kompakt geschrieben und verwendet eine Vielzahl von Fachtermini.

    Imho für OO, und somit zur Programierung in C++, unentbehrlich.

    => MUST HAVE READ <=

    Grüsse

    Gast++



  • Gast++ ich stimme voll mit dir überein. (nur weil ich oben in der thread-post-history noch eine frage zu templates gesehen hab [potenzierung mit templates], sage ich noch alexadrescu).

    Jedoch abgesehen von der Programmiersprache, möchte ich darauf hinweisen das jede art von paradigmatismus (in der religion vielleicht besser bekannt als fundamentalismus) nicht gut is. Man sollte immer die Mittel verwenden die einem am schnellsten ans Ziel bringen. (interfaces exkludiert, wenn möglich)

    Grüße

    WeaponX

    PS: Das ist übrigens mein erster post hier. (Ich schau schon lang zu) Aber ich finde Gast++ mit seiner sehr gut gewählten Ausdrucksweise es verdient eine Antwort zu erfahren, wenn es wen interessiert.

    Gast++ schrieb:

    Gamma, Helm, Johnson, Vlissides
    Entwurfsmuster
    Elemente wiederverwendbarer objektorientierter Software
    4. korrigierter Nachdruck Addison Wesley 1996
    ca. 480 Seiten
    ca. EUR 50,00

    Die "Gang of Four"(aka "GoF"), beim Artikel zu ihrem Werk zu finden http://en.wikipedia.org/wiki/Design_Patterns,
    und ihr Werk sind "Grale" der Softwaretechnik.

    Dies Buch hat einen solch immensen Einfluss auf Sprachen, Bibliotheken, ganze Entwicklungssysteme gehabt, dass die heutige Softwarelandschaft ohne dies schwer vorstellbar ist.

    Das Buch gleidert sich in drei Teile:

    - Einführung
    - Fallbeispiel - ein Dokumenteneditor
    - Musterkatalog,

    letzterer unterteilt in 5 Erzeugungsmuster (z.B. "Singleton"), 7 Strukturmuster ( z.B. "Proxy" ) und 11 Verhaltensmuster ( z.B. "Schablonenmethode" ).

    Verwandt wird die OMT-Notation, die sich aber mit UML-Kennntnissen ohne weiteres lesen laßt. Codebeispiele sind meist in C++ formuliert.

    im Einband findet sich ein Übersicht über die Notation un den Musterkatalog.

    Jedes Muster wird mit einem konkreten Beispiel mit einm Diagramm und einer Abtraktion, ebenfalls wieder mit einem Diagramm, erläutert.
    Pro und Contra des Musters werden schnökellos dargestellt.

    Wenn man die Dokumentation zu Programmbibliotheken und Frameworks liest wird man häufig auf die Begrifflichkeit der GoF stossen ohne dass diese noch extra erklärt wird oder die Quelle genannt.
    Meines Erachtens liegt dies daran dass viele Entwickler die solch komplexe Software schreiben, die Begrifflichkeit schon soweit verinnerlicht haben dass es ihnen in Fleisch und Blut übergegangen ist.

    Nachdem man sich mit dem Buch vetraut gemacht hat, kann man imo mit jeder OO-Programiersprache, egal wie genau man sie vorher kannte, effizienter umgehen.

    Die GoF legt sehr grossen Wert auf "Schnittstellen-Vererbung" ( Gegensatz: "Implementierungsvererbung") und verwendet sehr häufig eine abstrakte Basisklasse die Clienten einen Zugriffspunkt bereitstellt.

    Die Methodik ( obwohl nicht als extra "Muster" aufgenommen ) findet sich in unzähligen Bibliotheken und Frameworks wieder.

    Allerdings ist dieses Buch nicht gerade enfach zu lesen; es ist sehr kompakt geschrieben und verwendet eine Vielzahl von Fachtermini.

    Imho für OO, und somit zur Programierung in C++, unentbehrlich.

    => MUST HAVE READ <=

    Grüsse

    Gast++



  • Gast++ schrieb:

    Imho für OO, und somit zur Programierung in C++, unentbehrlich.

    Das unterstellt, dass man in C++ zwangsläufig OO programmieren würde.



  • Konrad Rudolph schrieb:

    Gast++ schrieb:

    Imho für OO, und somit zur Programierung in C++, unentbehrlich.

    Das unterstellt, dass man in C++ zwangsläufig OO programmieren würde.

    Nein.
    Es impliziert aus das es meine Meinung ist dass man dies tun sollte.
    😉

    Grüsse

    Gast++



  • Gast++ schrieb:

    Konrad Rudolph schrieb:

    Gast++ schrieb:

    Imho für OO, und somit zur Programierung in C++, unentbehrlich.

    Das unterstellt, dass man in C++ zwangsläufig OO programmieren würde.

    Nein.
    Es impliziert aus das es meine Meinung ist dass man dies tun sollte.

    Gut, das kommt aufs selbe raus. In C++ ist es aber nicht unbedingt besonders angesagt, OOP zu programmieren. Es geht natürlich, doch andere Sprachen sind dafür besser geeignet (schon deswegen, weil die STL nicht gerade für OOP ausgelegt ist). In C++ kann man andere Paradigmen wählen, z.B. die generische Programmierung.

    Worauf ich hinaus will: Ich programmiere so gut wie nie OO in C++.



  • Konrad Rudolph schrieb:

    Gast++ schrieb:

    Konrad Rudolph schrieb:

    Gast++ schrieb:

    Imho für OO, und somit zur Programierung in C++, unentbehrlich.

    Das unterstellt, dass man in C++ zwangsläufig OO programmieren würde.

    Nein.
    Es impliziert aus das es meine Meinung ist dass man dies tun sollte.

    Gut, das kommt aufs selbe raus.

    Nein. Ich schreibe nichts über Zwangsläufigkeit.

    Konrad Rudolph schrieb:

    In C++ ist es aber nicht unbedingt besonders angesagt, OOP zu programmieren.

    Das ist also Deine Meinung dazu.

    Stroustrup sieht das offenbar anders (C++-PL §24.2.2))
    Gamma et al. coden in C++.
    C++ unterstützt ausser Metaklassen alle von Booch definierten Merkmale von OO-Sprachen...

    Konrad Rudolph schrieb:

    Es geht natürlich, doch andere Sprachen sind dafür besser geeignet (schon deswegen, weil die STL nicht gerade für OOP ausgelegt ist).

    Die STL ist nicht zum Ableiten von eigenen Klassen ausgelegt.
    Aber es gilt auch nicht unbedingt als Guter Stil KLassenbibliothen in die Vererbungshierarchie einzubinden; Aggregation ist ein Stichwort dazu.

    Konrad Rudolph schrieb:

    In C++ kann man andere Paradigmen wählen, z.B. die generische Programmierung.

    Dass kann auf C++ als eigenstädiges Paradigma keine Anwendung finden. Das hiesse ja sich auf Funtionstemplates zu beschränken, also keine Klassen zu modellieren.
    Damit würde aber die Syntax nicht ausgenutzt.

    Grüsse

    Gast++



  • Gast++ schrieb:

    Konrad Rudolph schrieb:

    Es geht natürlich, doch andere Sprachen sind dafür besser geeignet (schon deswegen, weil die STL nicht gerade für OOP ausgelegt ist).

    Die STL ist nicht zum Ableiten von eigenen Klassen ausgelegt.

    Das meine ich nicht. Ich meine, dass die STL-Container nicht besonders gut zum Verwalten polymorpher Objekte geeignet sind. Die Tatsache, dass man sich um die Speicherverwaltung größtenteils selbst kümmern muss, macht das Arbeiten mit polymorphen Objekte doch recht aufwendig. Natürlich ist es möglich, aber dafür braucht man einfach C++ nicht. Da kann man auch andere Sprachen, wie z.B. Java verwenden. C++ hat hier einfach keinen Vorteil.

    Konrad Rudolph schrieb:

    In C++ kann man andere Paradigmen wählen, z.B. die generische Programmierung.

    Dass kann auf C++ als eigenstädiges Paradigma keine Anwendung finden. Das hiesse ja sich auf Funtionstemplates zu beschränken, also keine Klassen zu modellieren.
    Damit würde aber die Syntax nicht ausgenutzt.

    Quark. Generische Programmierung schließt die Verwendung von Klassen nicht aus. Das Verwenden von Klassen ist ja nicht nur mit OOP möglich. Wenn man sich die STL anschaut, oder auch andere Bibliotheken, die für C++ entwickelt werden (Boost, Loki ...) dann sieht man, dass der Aspekt der generischen Programmierung oft einen größeren Teil einnimmt als OOP.

    Wenn man sich anschaut, was der Erfinder der STL, Stepanov dazu zu sagen hat, wird deutlich, dass der zentrale Punkt bei der Entwicklung der STL die generische Programmierung war.



  • Ich fasse meine Gedanken noch einmal zusammen, um sie deutlicher zu machen.

    Man kann vielleicht zwischen Prä-STL- und Post-STL-C++ unterscheiden. Prä-STL-C++ war sicherlich usrprünglich als objektorientierte Erweiterung zu C gedacht. Aber dieser Fokus hat sich mit Einführung der STL einfach verschoben. C++' Stärke gegenüber anderen, modernen Programmiersprachen ist sicher nicht, dass es OOP beherrscht.

    Ich arbeite gerade an einer C++-Bibliothek für Bioinformatiker mit. OOP ist hier aus Performance-Gründen tabu und nur in absoluten Ausnahmen erlaubt. Vielmehr wird ein Methoden-Dispatching zur Compilezeit verwendet, wie es durch die generische Programmierung erlaubt wird.



  • Konrad Rudolph schrieb:

    Natürlich ist es möglich, aber dafür braucht man einfach C++ nicht. Da kann man auch andere Sprachen, wie z.B. Java verwenden. C++ hat hier einfach keinen Vorteil.

    Ob C++ oder eine andere Sprache besser besser für Polymophie geeignet sind war hier nicht das Thema; darauf bezog sich weder mein Statement über C++ noch Denie Antwort.

    Konrad Rudolph schrieb:

    In C++ kann man andere Paradigmen wählen, z.B. die generische Programmierung.

    Man kann damit auch prozedural programmieren.
    Nur ist meine These dass man das nicht tun sollte - wenn man prozedural programmieren will kann man C nehmen.

    "Ein bisschen OO", also Klassen in prozeduralem Code verwenden, geht meistens schief.
    Z.B. ist das Konzept "Ressourcebelegung ist Initialisierung" prozedural nicht abzubilden wenn man sich nicht der besodern Bedeutung von Konstruktoren/Destruktoren gewärtig ist.

    Konrad Rudolph schrieb:

    Dass kann auf C++ als eigenstädiges Paradigma keine Anwendung finden. Das hiesse ja sich auf Funtionstemplates zu beschränken, also keine Klassen zu modellieren.
    Damit würde aber die Syntax nicht ausgenutzt.

    Quark. Generische Programmierung schließt die Verwendung von Klassen nicht aus.

    Eben. Genau das war eine notwendige Implikation meiner These ("nicht eigenständig").
    Also wieso ist das Quark wenn's nicht von Dir kommt?

    Konrad Rudolph schrieb:

    Das Verwenden von Klassen ist ja nicht nur mit OOP möglich.

    s.o.

    Konrad Rudolph schrieb:

    Wenn man sich die STL anschaut, oder auch andere Bibliotheken, die für C++ entwickelt werden (Boost, Loki ...) dann sieht man, dass der Aspekt der generischen Programmierung oft einen größeren Teil einnimmt als OOP.

    Boost nutzt Kapselung, somit auch das OO-Paradigma.

    Konrad Rudolph schrieb:

    Wenn man sich anschaut, was der Erfinder der STL, Stepanov dazu zu sagen hat, wird deutlich, dass der zentrale Punkt bei der Entwicklung der STL die generische Programmierung war.

    Das mag sein, nur stehen sich die beiden Konzepte nicht diametral gegenüber.

    Grüsse

    Gast++

    P.S.: Du polemisierst hier ein wenig.



  • Konrad Rudolph schrieb:

    Ich arbeite gerade an einer C++-Bibliothek für Bioinformatiker mit. OOP ist hier aus Performance-Gründen tabu

    Jetzt ist zumindest klar warum Du auf die Eigenständigkeit "Generischer Programmierung" mit C++ Wert legst.

    Konrad Rudolph schrieb:

    Methoden-Dispatching zur Compilezeit

    Damit wollt späte Bindung mittels VMT umgehen?

    Idealerweise könnte ein Compiler das zu lediglich einem weiteren

    Assembler

    mov <wohinauchimmer>,<ein ptr>

    (o.ä.) optimieren.

    (Ich behaupte nicht dass Compiler das auch schaffen!)

    Mich würde mal Deine Messung des aktuellen Perfomance-Unterschieds
    (Compiler?, Optionen?)

    und das Kompliat, also der Assembler-Zwischencode, interessieren.

    Grüsse

    Gast++



  • Gast++ schrieb:

    P.S.: Du polemisierst hier ein wenig.

    Ja. Weil es mich ärgert, dass alle immer denken, Klassen gäbe es nur in OOP. Das ist einfach falsch und da entstehen ärgerliche Missverständnisse. Zum Beispiel hast Du in Deinem letzten Posting geschrieben:

    Boost nutzt Kapselung, somit auch das OO-Paradigma.

    Diese Aussage ist einfach falsch. Kapselung hat a priori rein gar nichts mit OOP zu tun. "Zufälligerweise" verwendet OOP *auch* Kapselung. Aber Deine Aussage ist eine falsche Implikation, genauso wie der berühmt-berüchtigte Syllogismus "Aristoteles ist sterblich. Katzen sind sterblich. Also ist Aristoteles eine Katze." -- natürlich ist Aristoteles keine Katze, nur weil er eine Eigenschaft mit ihnen teilt (die Sterblichkeit) und genausowenig ist alles, was Kapselung verwendet, gleich OOP, nur weil dieser Code mit OOP eine Eigenschaft (die Kapselung) teilt. Kapselung gab es schon lange vor OOP.

    Genauso ist der Rest Deiner Aussagen:

    "Ein bisschen OO", also Klassen in prozeduralem Code verwenden, geht meistens schief.

    -- Klassen in prozeduralem Code sind *nicht* zwangsläufig "ein bisschen OO". Nur weil OOP zufälligerweise Klassen verwendet, ist nicht jede Verwendung von Klassen OOP.

    Z.B. ist das Konzept "Ressourcebelegung ist Initialisierung" prozedural nicht abzubilden wenn man sich nicht der besodern Bedeutung von Konstruktoren/Destruktoren gewärtig ist.

    -- Weder RAII noch das Konzept von Konstruktor/Destruktor hat zwangsläufig etwas mit OOP zu tun.

    wenn man prozedural programmieren will kann man C nehmen.

    -- In C kann man aber eben (längst nicht so gut) generisch programmieren. C unterstützt keine ausreichend gute Kapselung. C unterstützt keine partiellen Spezialisierungen und Funktionsobjekte. C hat einen viel zu geringen Abstraktionsgrad. => C ist für die generische Programmierung ungeeignet.

    Zugegeben, ich war auch mal so weit, dass ich dachte, OOP sei das absolute Nonplusultra und wenn man schon Klassen verwendet, dann sollte bitte auch *alles* OOP sein. Aber inzwischen habe ich einfach begriffen, dass das nicht zutrifft. Die Ansicht, OOP sei das Nonplusultra ist genauso eine Modeerscheinung wie Hip-Hop oder der Minirock.



  • Gast++ schrieb:

    Damit wollt späte Bindung mittels VMT umgehen?

    Idealerweise könnte ein Compiler das zu lediglich einem weiteren

    Assembler

    mov <wohinauchimmer>,<ein ptr>

    (o.ä.) optimieren.

    Nein, es muss zumindest eine Zeigeraddition (Basisadresse + Offset in der VTable) stattfinden. Außerdem verhindert dies das Inlinen von Methoden.

    Das dadurch entstehende Overhead ist ein absolutes Totschlagargument gegen die Verwendung in dermaßen rechenintensiven Algorithmen.

    Mich würde mal Deine Messung des aktuellen Perfomance-Unterschieds […] interessieren.

    Sorry, ich selbst habe keine Messungen mit dieser Bibliothek durchgeführt. Dazu werden aber im Moment (mindestens) zwei Promotionen geschrieben. Ich glaube, diejenigen würden mir den Kopf abreißen, wenn ich einfach so deren Ergebnisse veröffentlichen würde. 😉



  • [quote="Konrad Rudolph"]

    Gast++ schrieb:

    Damit wollt späte Bindung mittels VMT umgehen?

    Idealerweise könnte ein Compiler das zu lediglich einem weiteren

    Assembler

    mov <wohinauchimmer>,<ein ptr>

    (o.ä.) optimieren.
    Nein, es muss zumindest eine
    Zeigeraddition (Basisadresse + Offset in der VTable)

    Das wäre ja i.d.R. noch besser...

    (Du polemisirst wirklich)

    Konrad Rudolph schrieb:

    stattfinden. Außerdem
    verhindert dies

    Welches "dies"?

    Konrad Rudolph schrieb:

    das Inlinen von Methoden.
    Das dadurch entstehende Overhead ist ein absolutes Totschlagargument gegen die Verwendung in dermaßen rechenintensiven Algorithmen.

    s.o.

    Wie und wo wird in dem Projekt eigentlich alloziert?
    (Das ist eins meiner Schwerpunktthemen)

    Mich würde mal Deine Messung des aktuellen Perfomance-Unterschieds […] interessieren.

    Konrad Rudolph schrieb:

    Sorry, ich selbst habe keine Messungen mit dieser Bibliothek durchgeführt. Dazu werden aber im Moment (mindestens) zwei Promotionen geschrieben. Ich glaube, diejenigen würden mir den Kopf abreißen, wenn ich einfach so deren Ergebnisse veröffentlichen würde. 😉

    Das ist schade, aber bis ich Zahlen sehe gehe ich davon aus dass die Doppelte Indirektion eben nicht wesentlich ins Gewicht fällt.

    Grüsse

    Gast++



  • Gast++ schrieb:

    Konrad Rudolph schrieb:

    Nein, es muss zumindest eine
    Zeigeraddition (Basisadresse + Offset in der VTable)

    Das wäre ja i.d.R. noch besser...

    Nö ... das kommt ja noch zum Aufruf *hinzu*.

    Konrad Rudolph schrieb:

    stattfinden. Außerdem
    verhindert dies

    Welches "dies"?

    Na, die virtuelle Funktion bzw. die dadurch entstehende Indirektion. Da der Compiler nicht weiß, welche Methode aufgerufen wird, kann er sie eben nicht inlinen. Das ist bei der Parametrisierung von Algorithmen ein recht großer Unterschied.

    Wie und wo wird in dem Projekt eigentlich alloziert?

    Was meinst Du damit? Wie Heapspeicher angefodert wird? Wie wir den Speicher verwalten? Oder generell wie Objekte konstruiert werden?

    Das ist schade, aber bis ich Zahlen sehe gehe ich davon aus dass die Doppelte Indirektion eben nicht wesentlich ins Gewicht fällt.

    Also, es lässt sich recht leicht illustieren, dass genau dies sehr wohl ins Gewicht fällt.

    Nimm mal die 'qsort'-Funktion aus C und die 'sort'-Funktion aus C++. Angenommen, die beiden Funktionen besäßen denselben Algorithmus (Quicksort, average case O(n log n)). In C wird ein Funktionszeiger übergeben, der jedes Mal aufgerufen werden muss. In C++ hingegen kann man einen Funktor übergeben, der geinlined werden kann. Die Laufzeit ist n log n, d.h. es wird in C n log n-mal eine Funktion aufgerufen, die oft eine an sich triviale Operation (einen Vergleich) ausführt. D.h. im Vergleich zu dem, was passiert, nimmt der Aufruf einen großen Anteil der Verarbeitungszeit in Anspruch. In C++ fällt dieses Overhead komplett flach. Der Laufzeitunterschied ist hier nicht zu verachten.

    Man beachte, dass der Funktionszeiger natürlich keine virtuelle Funktion ist, d.h. hier fällt sogar noch die Addition des Offsets flach. Wenn man hier mit einer virtuellen Funktion arbeiten würde, wäre der Unterschied noch größer. Ich habe gerade keine Zahlen im Kopf aber der Unterschied ist merklich. Generell fallen solche Unterschiede immer dann ins Gewicht, wenn sie sich in einem Algorithmus in der zentralen Schleife befinden. Leider kommt genau diese Situation in sehr vielen Algorithmen vor.



  • Konrad Rudolph schrieb:

    Gast++ schrieb:

    Konrad Rudolph schrieb:

    Nein, es muss zumindest eine
    Zeigeraddition (Basisadresse + Offset in der VTable)

    Das wäre ja i.d.R. noch besser...

    Nö ... das kommt ja noch zum Aufruf *hinzu*.

    Da ist mir, wie auch in Deinem folgenden Absatz, zuviel Mustmassung drin:

    mov <wohinauchimmer>,[Offset + Displacement]

    ginge nämlich auch.

    Konrad Rudolph schrieb:

    Das ist schade, aber bis ich Zahlen sehe gehe ich davon aus dass die Doppelte Indirektion eben nicht wesentlich ins Gewicht fällt.

    Also, es lässt sich recht leicht illustieren, dass genau dies sehr wohl ins Gewicht fällt.

    Nimm mal die 'qsort'-Funktion aus C und die 'sort'-Funktion aus C++. Angenommen, die beiden Funktionen besäßen denselben Algorithmus (Quicksort, average case O(n log n)). In C wird ein Funktionszeiger übergeben, der jedes Mal aufgerufen werden muss. In C++ hingegen kann man einen Funktor

    Ja, und?

    Konrad Rudolph schrieb:

    d.h. es wird in C n log n-mal eine Funktion aufgerufen, die oft eine an sich triviale Operation (einen Vergleich) ausführt. D.h. im Vergleich zu dem, was passiert, nimmt der Aufruf einen großen Anteil der Verarbeitungszeit in Anspruch. In C++ fällt dieses Overhead komplett flach. Der Laufzeitunterschied ist hier nicht zu verachten.

    Man beachte, dass der Funktionszeiger natürlich keine virtuelle Funktion ist, d.h. hier fällt sogar noch die Addition des Offsets flach.

    Eben.

    Konrad Rudolph schrieb:

    Die Laufzeit ist n log n,

    Das ist nicht die Laufzeit, sondern die Komplexität von Quicksort.
    Die wird durch jeweils einen weiteren Befehl mit konstanter Laufzeit nicht verändert.

    Konrad Rudolph schrieb:

    Wie und wo wird in dem Projekt eigentlich alloziert?

    Was meinst Du damit? Wie Heapspeicher angefodert wird? Wie wir den Speicher verwalten? Oder generell wie Objekte konstruiert werden?

    Zwar bin ich mir sicher dass Du Dir das aus dem Kontext erschliessen könntest, aber sei's drum:
    Allokation von Arbeitsspeicher.

    Insbesondere interessiert mich übrigens der Umgang mit new().

    Grüsse

    Gast++



  • Konrad Rudolph schrieb:

    Gast++ schrieb:

    P.S.: Du polemisierst hier ein wenig.

    Ja.

    Das lass ich mal so stehen.

    Konrad Rudolph schrieb:

    Boost nutzt Kapselung, somit auch das OO-Paradigma.

    Diese Aussage ist einfach falsch.

    Diese Aussage hingegen wäre nur dann zwingend richtig, wenn es keinen Kontext gäbe innerhald dessen wir hier argumentierten.

    Konrad Rudolph schrieb:

    Aber Deine Aussage ist eine falsche Implikation, genauso wie der berühmt-berüchtigte Syllogismus "Aristoteles ist sterblich. Katzen sind sterblich. Also ist Aristoteles eine Katze."

    Das ist aber dann richtig wenn man dabei auf einen Käfig nur mit Katzen und Katzenspielzeug zeigt. Und wir diskutieren hier über hier eine Katze namens C++.

    Konrad Rudolph schrieb:

    ist nicht jede Verwendung von Klassen OOP.

    Genau. Und unter andeerem deshalb führt das auch zu Problemen.

    Konrad Rudolph schrieb:

    Z.B. ist das Konzept "Ressourcebelegung ist Initialisierung" prozedural nicht abzubilden wenn man sich nicht der besodern Bedeutung von Konstruktoren/Destruktoren gewärtig ist.

    -- Weder RAII noch das Konzept von Konstruktor/Destruktor hat zwangsläufig etwas mit OOP zu tun.

    Aber gerade die STL schafft hier eine Verbindung und somit auch Notwendigkeiten.

    Konrad Rudolph schrieb:

    Zugegeben, ich war auch mal so weit, dass ich dachte, OOP sei das absolute Nonplusultra und wenn man schon Klassen verwendet, dann sollte bitte auch *alles* OOP sein. Aber inzwischen habe ich einfach begriffen, dass das nicht zutrifft. Die Ansicht, OOP sei das Nonplusultra ist genauso eine Modeerscheinung wie Hip-Hop oder der Minirock.

    Soweit war ich noch nie.
    Aber lass uns bitte beim Thema bleiben.
    Pro und Contra OOP führt hier zu weit.

    Grüsse

    Gast++



  • Gast++ schrieb:

    Da ist mir, wie auch in Deinem folgenden Absatz, zuviel Mustmassung drin:

    mov <wohinauchimmer>,[Offset + Displacement]

    ginge nämlich auch.

    Korrigier mich, wenn's falsch ist aber meinen beschränkten x86-ASM-Kenntnissen zufolgen kann das Displacement nicht eine beliebige Zahl sein sondern nur bestimmte Werte. Zumindest ist das in den meisten Assemblern so. Und damit wäre dieser Opcode ungeeignet.

    Konrad Rudolph schrieb:

    Die Laufzeit ist n log n,

    Das ist nicht die Laufzeit, sondern die Komplexität von Quicksort.

    Das ist doch für die Diskussion total egal, zumal ich bereits vorher die Landau-Notation erwähnt hatte. Die Laufzeit ist linear zur Komplexität des Algorithmus. Und damit gilt: Es wird k*n*logn-mal dieser Sprung ausgeführt -- das ist eine Menge!

    Die wird durch jeweils einen weiteren Befehl mit konstanter Laufzeit nicht verändert.

    Das ist mir bewusst, genau darum geht es aber doch: Der Algorithmus wird um einen konstante Faktor verlangsamt -- und zwar unnötigerweise -- und dieser Faktor ist messbar. Bei aufwendigen Berechnungen kann man sich sowas einfach nicht leisten. Bei einem einfachen Quicksort ist das nicht besonders tragisch aber bei der Sequenzierung eines Genoms entscheidet dieser konstante (!) Faktor darüber, ob das Projekt finanzierbar ist oder nicht. Die Sequenzierung des menschlichen Genoms hat grob zehn Jahre gebraucht! Wenn die Berechnung auch nur um einen Faktor zwei langsamer gewesen wäre, hätte man das Projekt nicht finanzieren können! Bei solchen Größenordnung ist man auf jedes Quentchen Geschwindigkeit angewiesen, selbst auf eine konstante Verbesserung.

    Konrad Rudolph schrieb:

    Wie und wo wird in dem Projekt eigentlich alloziert?

    Was meinst Du damit? Wie Heapspeicher angefodert wird? Wie wir den Speicher verwalten? Oder generell wie Objekte konstruiert werden?

    Zwar bin ich mir sicher dass Du Dir das aus dem Kontext erschliessen könntest, aber sei's drum:

    Grmpf. Wenn ich es erschlossen hätte, hätte ich nicht nachgefragt. Kaugummidiskussionen machen (zumindest mir) *keinen* Spaß.

    Wozu ist denn die Art der Allokation in diesem Kontext interessant?

    Sei's drum. Dynamischer Speicher wird in der Bibliothek vorzugsweise über eigene Allokatoren bereitgestellt. Der Standardallokator verwendet intern soweit ich das gerade sehe placement new. Es gibt aber je nach Benutzung recht unterschiedliche Allokationsstrategien.


Anmelden zum Antworten