Verleitet die Mächtigkeit der Sprache C++ dazu es kompliziert zu machen?



  • n3wbie schrieb:

    Wenn der Browser zu langsam ist, macht es Sinn herauszufinden warum er zu langsam ist, und die Umsetzung zu verbessern. Dann kann man immer noch über die Sprache nachdenken.

    Bei einem Browser soll aber sogut wie alles schnell sein. Er soll schnell starten, html und Javascript schnell verarbeiten, Bilder schnell laden. Dazu soll er auch mit so wenig Speicher wie moeglich auskommen. Das ganze geht um Geschwindigkeiten, die mit etwas anderem kaum realisierbar sind. Das ganze muss dann auch moeglichst Cachefreundlich sein, was in anderen Sprachen kaum zu beeinflussen ist.
    In C++ wird sogar auf Exceptions verzichtet, um die Geschwindigkeit nicht zu beeintraechtigen.



  • tntnet schrieb:

    IBV schrieb:

    Das ist superkurz und elegant und hat noch einen Errorhandling!

    case class User(name: String, email: String, pwd: String)
    
    object User {
      implicit val userReads: Reads[User] = Json.reads[User]
      implicit val userWrites: Writes[User] = Json.writes[User]
      implicit def userToJson(user: User) = Json.toJson(user)
    }
    
    def registerUser = Action(BodyParsers.parse.json) { request =>
      request.body.validate[User] match {
        case jsUser: JsSuccess[User] => // Do something
        case error: JsError => // Error Handling
      }
    }
    

    Um welche Programmiersprache handelt es sich hier? Ich kann kein Java erkennen.

    Scala.



  • Marthog schrieb:

    In C++ wird sogar auf Exceptions verzichtet, um die Geschwindigkeit nicht zu beeintraechtigen.

    Quelle?



  • SeppJ schrieb:

    In Fuß schießen ist doof schrieb:

    Soviel zum Thema 🙄

    Zum Thema welche Torrentclient der kleinste ist. Wie du da den Zusammenhang zu "Verleitet die Mächtigkeit der Sprache C++ dazu es kompliziert zu machen?" siehst, magst du nicht verraten, oder? Ich hoffe jedenfalls nicht, dass du wirklich glaubst, dass die Executables durch Wahl der Sprache eine wesentlich andere Größe hätten.

    C++ Templates führen zu Codeduplizierung. Allerdings weiß ich nicht wie teuer das ist.

    L. G.,
    IBV



  • volkard schrieb:

    Marthog schrieb:

    In C++ wird sogar auf Exceptions verzichtet, um die Geschwindigkeit nicht zu beeintraechtigen.

    Quelle?

    Google Style Guide? Gut, die machen das hauptsächlich wegen Legacycode.
    LLVM Style Guide? Gut, das ist kein Browser.



  • IBV schrieb:

    C++ Templates führen zu Codeduplizierung. Allerdings weiß ich nicht wie teuer das ist.

    Das ist schon wieder etwas, was zum Thema passt. An sich können Compiler mit Codebloat durch Templates relativ gut umgehen. Aber man schreibt ja oft so komplizierte Templates, dass man das eigentliche Problem ganz anders löst, als eine direkte Lösung aussehen würde. Da wird dann auch wahrscheinlich deutlich mehr Code generiert werden, als bei einer einfachen Lösung. Ist aber nicht so relevant.
    Aber ja, an der Stelle würde ich auch sagen, dass die Mächtigkeit mich an der Stelle ab und zu dazu verleitet, etwas komplizierter als unbedingt nötig zu machen.



  • Mechanics schrieb:

    IBV schrieb:

    C++ Templates führen zu Codeduplizierung. Allerdings weiß ich nicht wie teuer das ist.

    Das ist schon wieder etwas, was zum Thema passt. An sich können Compiler mit Codebloat durch Templates relativ gut umgehen. Aber man schreibt ja oft so komplizierte Templates, dass man das eigentliche Problem ganz anders löst, als eine direkte Lösung aussehen würde. Da wird dann auch wahrscheinlich deutlich mehr Code generiert werden, als bei einer einfachen Lösung. Ist aber nicht so relevant.

    Naja, wenn unterschiedliche Typen für den selben Algo unterschiedliche Code-Locations haben, klappts wiederum die Sprungvorhersage besser. Die ganz kranken Templates, die wie hier immer sehen, machen eh ihr Ding zur Compilezeit. Dupliziertes sort<>() bläst wirklich viel besser als zentrales qsort(). Warum?

    Progs, die ein einfaches Problem ganz anders lösen, die sehe ich in jeder Sprache. Da sind die "generischen" Template-Lösungen von C++-Nubes noch harmlos gegenüber Dependency-Injection in Java/C# oder Ubiquitous-Lösungen in UML vom Chefchen, wenns um Kompliziertheit geht (nebst dadurch entstehender Langsamkeit und Unwartbarkeit).



  • Denke dass

    template<class Key, class Value, class Hash = DefaultHash<Key>, class Comp = DefaultComp<Value> >
    class HashTable;
    

    weit besser ist als mit soetwas zu hantieren:

    struct Hashtable {
        struct Entry {
            void const* key;
            void* value;
        };
    
        bool (*valueComp)(void* value1, void* value2);
        size_t (*keyHash)(void* key);
    };
    

    Also Performancetechnisch.



  • Ich meine sowas wie... Keine Ahnung, z.B. boost::serialization. Keine Ahnung, ob das wirklich Code Bloat erzeugt, nur als Beispiel. Etwas "direkt" zu serialisieren/lesen wäre dann vielleicht eine kleine Funktion, die ganz wenig Code hat. Eine Lösung mit Templates könnte dafür viel mehr zusätzlichen Code haben, den der Compiler zwar vielleicht ganz gut zusammenfasst, aber der an sich gar nicht nötig wäre.
    Gegen boost::serialization an sich wollte ich jetzt gar nichts sagen, habs noch nie verwendet und kenn das nicht genau.



  • Ethon schrieb:

    Also Performancetechnisch.

    Und es läßt weniger Flüchtigkeitsfehler durch zum Kunden.



  • Compiler, die Code deduplizieren, könnten viel einsparen. Ich weiß nicht, ob das aktuell ausgenutzt wird, aber die Methoden von vector<size_t> müssten zum Beispiel identischen Code generieren wie vector<T *> für beliebiges T oder andere PODs derselben Größe.

    Sparen können auch Bibliotheken intern. unordered_set<unsigned short> kann intern ein unordered_set<size_t> verwenden, weil das praktisch der gleiche Maschinencode ist. Die Übersetzungsschicht zwischen den Typen sollte natürlich möglichst inline sein.

    Manchmal kann man konkrete T* durch void* ersetzen und damit Code gemeinsam nutzen.



  • TyRoXx schrieb:

    Compiler, die Code deduplizieren, könnten viel einsparen. Ich weiß nicht, ob das aktuell ausgenutzt wird, aber die Methoden von vector<size_t> müssten zum Beispiel identischen Code generieren wie vector<T *> für beliebiges T oder andere PODs derselben Größe.

    Die Compiler versuchen dass schon, ich habe aber nie ueberpreuft, wie gut sie das auch schaffen.

    TyRoXx schrieb:

    Manchmal kann man konkrete T* durch void* ersetzen und damit Code gemeinsam nutzen.

    Das wird in der Standard-library schon manchmal gemacht. Hat zumindest Stefen T. Lavavey mal erzaehlt, dass sie sowas machen, um das Maximum an Geschwindigkeit herauszuholen.



  • Type-Erasure wird auch in der Boost an einigen Stellen gemacht um Template-Bloat zu vermindern.
    Bzw. allgemein das Zerteilen von Klassentemplates in zwei oder manchmal sogar mehr Klassen.

    @Mechanics
    Was Boost.Serialization an Template Bloat erzeugt oder nicht erzeugt, ist denke ich ganz gut vergleichbar damit was bestimmte Algorithmen an Template Bloat erzeugen.
    Wenn man std::sort mit zig verschiedenen Containern aufruft, dann erzeugt das Template Bloat. Dafür läuft es halt meist auch schneller *.

    Genau so ist es mit Boost.Serialization und verschiedenen Archive Typen.

    *: Bis auf diverse Extremfälle. z.B. wenn durch dauernden Wechsel zwischen den verschiedenen Template-Instanzen der Instruction Cache so schlecht ausgenutzt wird, dass die Vorteile des Inlining zunichte gemacht werden.

    EDIT: Sorry, das meiste ist ja bloss nachgeplappert von was schon früher in diesem Thread steht. Hab' vor dem Posten nicht alles gelesen 🙂


Anmelden zum Antworten