GC vs RAII



  • try-with-resources ist für mich überhaupt kein Ersatz für RAII.
    Das gab es im Prinzip schon immer, denn es macht ja nichts anderes als daraus ein try...catch...finally{dispose} zu basteln.
    Es verkürzt einfach nur die Schreibweise.
    Aber ich muss (müsste) weiterhin bei jeder Klasse die ich verwende nachschauen, ob die gerne was disposen möchte.
    In C++ nutze ich einfach die Klasse und wenn die was aufräumen möchte, muss ich davon nichts wissen.



  • dachschaden schrieb:

    - Kann auch langsam sein. Sagen wir, du willst erst mal nur 100.000 Objekte auf dem Heap haben, diese aber nicht unbedingt initialisieren. Mit RAII hast du dann wieder 100.000 Calls des Konstruktors, die gemacht werden müssen.

    Der Unterschied ist, dass man in Java alles auf dem Heap anlegt und in C++ eher nicht.

    Wenn ich 100.000 Objekte in Java benötige, dann muss ich 100.000 mal new aufrufen und dynamischen Speicher anfordern. Das geht in Java sehr schnell.

    Wenn ich 100.000 Objekte in C++ benötige, dann lege ich einen std::vector mit 100.000 Elementen an, welcher alle 100.000 Elemente mit einem new-Aufruf alloziiert. Und das geht mit ziemlicher Sicherheit schneller, als die sehr schnellen 100.000 Aufrufe in Java.

    Ich gehe mal davon aus, dass beide Sprachen der Optimierer keine Probleme hat, den Konstruktoraufruf geeignet zu optimieren. In C++ habe ich möglicherweise einen Standardkonstruktor, welcher Inline ist. Da "sieht" der Compiler, was er machen muss und hat die Möglichkeit zu optimieren. Bei Java sieht er es zur Laufzeit und auch dort werden ähnliche Optimierungen erfolgen.

    In C++ programmiere ich eben anders. Daher ist es nicht sinnvoll, die Allokation von Speicher zu benchmarken, da ich in C++ eben weniger Allokationen machen muss.

    So nebenbei ist in C++ der Code zum anlegen von 100000 Elementen auch wesentlich übersichtlicher:

    std::vector<Point> points(100000);
    
    List<Point> points = new ArrayList<Point>();
    for (int i = 0; i < 100000; ++i)
      points.add(new Point());
    


  • dachschaden schrieb:

    So nebenbei ist in C++ der Code zum anlegen von 100000 Elementen auch wesentlich übersichtlicher:

    std::vector<Point> points(100000);
    
    List<Point> points = new ArrayList<Point>();
    for (int i = 0; i < 100000; ++i)
      points.add(new Point());
    

    Das ist jetzt ein Scherz oder? Soviel Code für so eine simple Sache?

    Mir ist auch eigentlich bei Java egal, ob das theoretisch langsamer oder gleich schnell wie C++ ist. Ich sehe Java-Anwendungen und sehe C++-Anwendungen und da gewinnt bei mir IMMER das C++-Programm in Sachen Performance.

    Habt ihr euch mal den neuen SceneBuilder für JavaFX angesehene? Der hat letzlich beim Ausprobieren, von einer Hand voll Widgets, meinen dicken i7 mit guter Grafikkarte locker in die Knie gezwungen. Da ist Battlefield4 genügsamer.


  • Mod

    Wann habt Ihr das letzte mal eine Liste mit 100.000 "Standardpunkten" benoetigt?

    Zeigt doch mal den Unterschied, wenn Ihr 100.000 Punkte erstellt, die alle auf einer Funktion liegen. Also zum Beispiel, wenn Ihr etwas plotten moechtet. Besser noch: Baut mal eine Methode, aus der Ihr so eine Liste an Punkten rauskriegt und zeigt diese inklusive dem Methodenaufruf.



  • tntnet! Du unterschlägst aber, das die C++ Variante nicht der Java-Variante entspricht!
    In deinem C++ Beispiel kann man nur Objekte genau eines Typs anlegen: Point! Und zwar ausschließlich Points, keine Objekte die von Point erben.

    Jetzt kann man natürlich sagen, ich brauche nur den einen Typ. Aber dann sage das auch. So ist der Vergleich leider für den Popo! Weil sobald du Point als Basis-Typ haben willst, ist der C++ Vorteil wieder dahin!



  • Artchi schrieb:

    Weil sobald du Point als Basis-Typ haben willst, ist der C++ Vorteil wieder dahin!

    std::vector<std::shared_ptr<Point>> points(size, std::make_shared<Point>());
    

    Macht in etwa dasselbe wie der Javacode und ist zeilenmäßig trotzdem besser.



  • Na also, wenn dann bitte gleich richtig. Geht doch! Aber das von Tntnet war ne Frechheit!

    Um die Codekürze ging es mir nicht vorrangig. Das ist nur nice-to-have. Es geht darum, was es macht und dann müssen beide Beispiel gleiches können.


  • Mod

    Nathan schrieb:

    std::vector<std::shared_ptr<Point>> points(size, std::make_shared<Point>());
    

    Macht in etwa dasselbe wie der Javacode und ist zeilenmäßig trotzdem besser.

    Ist immer noch irrelevant. Niemand braucht 100.000 Punkt Objekte, die alle mit dem Standardkonstruktor erstellt wurden und somit alle gleich sind.

    Wenn Ihr zu einem realistischeren Szenario geht, dann wird die Codelänge nicht mehr wesentlich von einander abweichen.



  • Gregor! Ja, das stimmt. Ich verstehe das Ziel dieses künstlichen Konstrukts auch nicht. In der Praxis sieht Code anders aus. Selbst für einen Unittest wäre das Beispiel unrealistisch.



  • Gregor schrieb:

    Nathan schrieb:

    std::vector<std::shared_ptr<Point>> points(size, std::make_shared<Point>());
    

    Macht in etwa dasselbe wie der Javacode und ist zeilenmäßig trotzdem besser.

    Ist immer noch irrelevant. Niemand braucht 100.000 Punkt Objekte, die alle mit dem Standardkonstruktor erstellt wurden und somit alle gleich sind.

    Insbesondere macht das nicht 100k Point Objekte, sondern einen Vektor aus 100k shared_ptr die alle auf das selbe Point Objekt verweisen... 😉


Anmelden zum Antworten