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



  • In Fuß schießen ist doof schrieb:

    SeppJ schrieb:

    In Fuß schießen is doof schrieb:

    Aus dem Grund nutze ich µTorrent als Torrent Client.
    Die anderen waren mir bisher alle zu fett.

    µTorrent <= 1 MB
    Irgendso ein anderer Torrent Client hat 60 MB benötigt.
    So groß waren früher höchstens C++ Compiler.

    Klar, denn das sind ganz klar 60 MB Bibliotheksfunktionen und Code. Keinesfalls könnten das 60 MB an GUI-Elementen sein. Ausgeschlossen. 🙄

    Afaik war das Deluge und das in einer der fetten Versionen wie man sie hier noch finden kann:

    http://download.deluge-torrent.org/archive/windows/0.9.02/

    Allein die Python Scripte sind entpackt allein schon 20 MB groß.

    Das ganze ist schon ein paar Jahre her, ich kann mich nur erinnern dass ich ein richtig fettes Packet downloaden musste.
    Die 40 MB könnten es gewesen sein, auch wenn ich eher 60 MB in Erinnerung habe.
    Auch weiß ich nicht mehr genau, wie fett das Teil dann im installierten Zustand gewesen ist. So etwa 60-120 MB waren es aber schon, denn ich war so geschockt von dem Platzverbrauch, dass ich mich dann bewusst für µTorrent entschied.

    Und Fakt ist, dass es mit dieser Größe nicht gegen µTorrent anstinken kann.
    Da sieht es richtig alt aus.
    Man stelle sich mal vor, man sucht nur nen Torrent Client.
    Will so etwas einfaches wie nur nen Torrent Client und dann kriegt man so ein Fettpaket.

    Da das ganze unter Windows laufen sollte, zählen die Supportlibs zur Platzverschwendung mit dazu.
    Das gleiche gilt für die Ladezeiten, wenn das ganze Geraffel geladen werden muss.

    Es ist schon erstaunlich. µTorrent kann genau das gleiche, aber es braucht nur einen Bruchteil des Platzes und ist Ratzfatz geladen, auch mit HD ohne SSD.

    Obwohl ich damals einen Crossplattformfähigen Open Source Torrent Clienten gesucht habe, habe ich mich dann nach dem Schock über den Platzverbrauch dann doch für den nur unfreien Freeware µTorrent Clienten entschieden.
    Lediglich für Linux habe ich dann einen anderen genommen.

    Aber eines steht fest, wer für so etwas im Prinzip kleines wie einen Torrent Clienten als Entwickler 40 MB verheizt, der gehört im Grunde bestraft.
    In 40 MB hat man früher ganze Betriebssysteme untergebracht und die haben mehr geleistet.

    Es ist ne Schande, so ein Platzfresser.

    Soviel zum Thema 🙄

    Zu jeder Sprache gibt es auch Nasen, die damit Mist bauen.
    C++ vom GCC hat als Fixkosten für ein Programm ca 30k mehr als C, nämlich Buffer für Exceptions und Code für wenn sie aus der main() fliegen und so ein Mist: nebenbei ausschließlich vermeidbares Zeugs, aber die GCC-Leute wollen offenbar C++ nicht auf µC sehen.
    Nimmt man noch <iostream>, kämen static gelinkt (wer macht das?) noch 500k dazu. Spaßigerwiese wieder mit Zwangsmitgliedschaft sobald man auch nur eine virtuelle Funktion (purecall-Handler) oder überhaupt Exceptions (unhandled) benutzt. Schon wieder leicht vermeidbar für die Compilerbauer aber ohne Compilerrecompilieren undmöglich.
    Die glibc frisst schon 1000k (static, aber wer macht das schon?), das sollte man nicht übersehen.
    Das war's aber auch dann schon. Deine gewaltigen Größen liegen nicht irgendwie an der Sprache.



  • volkard schrieb:

    Zu jeder Sprache gibt es auch Nasen, die damit Mist bauen.
    C++ vom GCC hat als Fixkosten für ein Programm ca 30k mehr als C, nämlich Buffer für Exceptions und Code für wenn sie aus der main() fliegen und so ein Mist: nebenbei ausschließlich vermeidbares Zeugs, aber die GCC-Leute wollen offenbar C++ nicht auf µC sehen.
    Nimmt man noch <iostream>, kämen static gelinkt (wer macht das?) noch 500k dazu. Spaßigerwiese wieder mit Zwangsmitgliedschaft sobald man auch nur eine virtuelle Funktion (purecall-Handler) oder überhaupt Exceptions (unhandled) benutzt. Schon wieder leicht vermeidbar für die Compilerbauer aber ohne Compilerrecompilieren undmöglich.
    Die glibc frisst schon 1000k (static, aber wer macht das schon?), das sollte man nicht übersehen.
    Das war's aber auch dann schon. Deine gewaltigen Größen liegen nicht irgendwie an der Sprache.

    Allein die Python Scripte sind entpackt allein schon 20 MB groß.



  • PS:

    Du kannst das Ding auch downloaden und nachmessen. Link steht oben.


  • Mod

    Jaja. Ein Linuxkernel ist nur 70 MB groß, Windows 8 kommt auf > 10 GB. Das liegt nur da dran, dass Linux in C geschrieben ist, Windows in MSVC++.



  • 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