Java in C++ programmieren - Programmier- und Designunterschiede



  • hustbaer schrieb:

    Wenn ich das richtig verstehe sind diese ARM Blöcke auch nix anderes als was "using" in C# ist? Dann wäre das zwar ... nunja, besser als nichts, aber IMO nicht wirklich ausreichend.

    Richtig, nur dass im Gegensatz zu C# mehr als eine Ressource pro Block möglich sein sollen.



  • fricky schrieb:

    hustbaer schrieb:

    Richtigerweise hätte ich wohl sagen sollen deterministische Finalisierung "die Java nicht unterstützt".

    dazu müsste man den java-GC austauschen, so dass er nach der letzen referenz sofort den speicher freigibt. dann wäre finalize() deterministisch. aber so isses das leider nicht.
    🙂

    nein. siehe c++/cli oder D
    das objekt modell ist das "problem"



  • Shade Of Mine schrieb:

    fricky schrieb:

    hustbaer schrieb:

    Richtigerweise hätte ich wohl sagen sollen deterministische Finalisierung "die Java nicht unterstützt".

    dazu müsste man den java-GC austauschen, so dass er nach der letzen referenz sofort den speicher freigibt. dann wäre finalize() deterministisch. aber so isses das leider nicht.
    🙂

    nein. siehe c++/cli oder D
    das objekt modell ist das "problem"

    nö, man könnte sogar den GC seine arbeit machen lassen wie bisher, nur dass 'finalize()' *sofort* aufgerufen wird, wenn die letzte referenz weg ist. dann wärs auch deterministisch.
    🙂



  • Nochmal: der GC weiß nicht, wann die letzte Referenz weg ist.



  • Von welchem GC redest du?



  • fricky schrieb:

    nö, man könnte sogar den GC seine arbeit machen lassen wie bisher, nur dass 'finalize()' *sofort* aufgerufen wird, wenn die letzte referenz weg ist. dann wärs auch deterministisch.
    🙂

    die performance kosten waeren enorm.



  • Shade Of Mine schrieb:

    die performance kosten waeren enorm.

    warum?
    🙂



  • fricky schrieb:

    Shade Of Mine schrieb:

    die performance kosten waeren enorm.

    warum?
    🙂

    befass dich mal mit GCs. Was du willst ist ein Refcounting GC und die sind ewig veraltet. GC mit deterministic finalization ist einfach nicht schnell implementierbar. Aber der GC ist auch der komplett falsche Ansatzpunkt. Du willst für die meisten Resourcen keine deterministische finalization haben. Die meisten Resourcen sind in Pools wie sie der GC anbietet perfekt aufgehoben.



  • 5%Sauerstoff schrieb:

    Man kann ja hier öfter sowas wie "man kann auch Java in C++ programmieren" lesen. Was sind denn die großen Unterschiede?

    1. C++ erlaubt Metaprogrammierung mit Templates. In Java kann man das manchmal mit Vererbung und Polymorphie nachbauen, manchmal muss man es ganz anders machen.
    2. C++ Objekte können auf den Stack und haben hat Destruktoren -> RAII möglich. In Java muss man überall try{} finally{} darum schreiben.
    3. In C++ kann man freie Funktionen in Namespaces stecken. In Java macht man das mit static Methoden in Klassen.

    Weitere?

    Ganz ehrlich: Es ist oft keine gute Idee eine Programmiersprache X, wie eine Programmiersprache Y zu benutzen. Jede Programmiersprache bringt eigene Strategien, Ideen und Konzepte mit.
    Natürlich kann man C++ schon sehr wie Java programmieren (gibt ja sogar GCs), wenn man eben alles in Klassen packt und große Hierarchien baut. Aber so programmiert man - zumindest heutzutage - eben kein C++ mehr, weil es nicht sonderlich effektiv ist, C++ so zu programmieren.

    Wie Blue-Tiger schon geschrieben hat, sind moderne C++-Programme oft eher funktional.



  • Ich dachte das ursprüngliche Konzept von C++ war, moderne Dinge wie OOP nach C zu bringen. Das C++ mehr als C mit Klassen ist, heißt nicht, dass C++ nicht OOP sein sollte.
    C++ ist doch eben Multiparadigmisch, sodass jeder so programmieren kann, wie er es als am sinnvollsten betrachtet und das ist für mich der Kerngedanke vom modernen C++ und nicht, dass auf einmal alles so aufgebaut ist wie die funktionalgenerische Standardbibliothek.

    Das man in C++ nicht so streng OOP programmiert wie in Java, ist klar, aber der funktionale Ansatz ist meines Erachtens veraltet und ein Schritt in die falsche Richtung(C++ funktional programmieren und C OOP scheint ja ein Trend zu sein).
    Ebenso ist die Templatemetaprogrammierung Schwachsinnig, solche Optimierung braucht kein Mensch, wenn dadurch das Programm derart unleserlich wird.
    Um auf deine Aussage zurückzukommen, effektiv ist anders.



  • !!! schrieb:

    der funktionale Ansatz ist meines Erachtens veraltet und ein Schritt in die falsche Richtung

    Setzen, 6.

    Aktuell ist die einzige Antwort die es auf die Multi-Core Problemstellung gibt: funktionales programmieren. Es gibt einfach keine andere vernünftige Antwort. OpenMP ist nett, aber wenn man sich Sachen wie Erlang ansieht oder moderne Konzepte wie plinq -> funktionale konzepte ueberall.

    Ebenso ist die Templatemetaprogrammierung Schwachsinnig, solche Optimierung braucht kein Mensch, wenn dadurch das Programm derart unleserlich wird.

    templatemetaprogrammierung != optimierung

    man _kann_ templatemetaprogrammierung zur laufzeitoptimierung verwenden, aber es ist nur ein einsatzgebiet von vielen...



  • Und um mehrere Kerne zu unterstützen, was zur Zeit sowieso nur wenige Anwendungen benötigen, soll man wie vor Urzeiten programmieren?
    Das ist doch schon wieder so eine Performanceoptimierung auf Kosten einer ordentlichen Software.
    Nur weil es in manchen Situationen notwendig ist, macht es das noch lange nicht modern oder erstrebenswert.



  • !!! schrieb:

    Und um mehrere Kerne zu unterstützen, was zur Zeit sowieso nur wenige Anwendungen benötigen, soll man wie vor Urzeiten programmieren?

    jetzt kommt das wirklich fiese: gerade für parallelisierung kann man mit templateprogrammierung das leben leichter machen, da sie viele automatische optimierung des compilers erst ermöglichen und händische leichter zugänglich machen. wenn es dich interessiert, schau dir mal die template-basierten lineare-algebra-libs an. die schaffen in c++, was sonst eigentlich nur in sprachen wie fortran mit der eingebauten vektorunterstützung, möglich ist. der code, den der "normale" anweder schreiben muss, ist nebenbei genauso wie sonst auch. das ist doch schicke an templates in c++...

    !!! schrieb:

    Das ist doch schon wieder so eine Performanceoptimierung auf Kosten einer ordentlichen Software.

    auch hier ein klassisches: nein. sie nutzen der software, da sie zum einen den wartungsaufwand verringern und zum anderem zur copilezeit vollständig ausgewertet werden. oder auch: ein template sagt dir viel früher, dass du auf dem falschen dampfer bist, als sein äquivalent in runtime-polymorphismus. (das ist nebenbei der grund, warum es seit java5 dort generics gibt...)



  • !!! schrieb:

    Und um mehrere Kerne zu unterstützen, was zur Zeit sowieso nur wenige Anwendungen benötigen, soll man wie vor Urzeiten programmieren?
    Das ist doch schon wieder so eine Performanceoptimierung auf Kosten einer ordentlichen Software.
    Nur weil es in manchen Situationen notwendig ist, macht es das noch lange nicht modern oder erstrebenswert.

    omg
    n/c



  • !!! schrieb:

    Und um mehrere Kerne zu unterstützen, was zur Zeit sowieso nur wenige Anwendungen benötigen, soll man wie vor Urzeiten programmieren?
    Das ist doch schon wieder so eine Performanceoptimierung auf Kosten einer ordentlichen Software.
    Nur weil es in manchen Situationen notwendig ist, macht es das noch lange nicht modern oder erstrebenswert.

    Struktiert != Funktional



  • Shade Of Mine schrieb:

    fricky schrieb:

    Shade Of Mine schrieb:

    die performance kosten waeren enorm.

    warum?
    🙂

    befass dich mal mit GCs. Was du willst ist ein Refcounting GC und die sind ewig veraltet. GC mit deterministic finalization ist einfach nicht schnell implementierbar. Aber der GC ist auch der komplett falsche Ansatzpunkt. Du willst für die meisten Resourcen keine deterministische finalization haben. Die meisten Resourcen sind in Pools wie sie der GC anbietet perfekt aufgehoben.

    Korrekt, die meisten Resourcen.

    Für die Resourcen für die man allerdings deterministische Finalisierung haben möchte (oder muss) ist das aber keine Lösung.

    Dummerweise färbt die Forderung "muss deterministisch finalisiert werden" ab: wenn eine Klasse X eine Klasse Y als Member oder Basisklasse verwendet, und Y deterministisch finalisiert werden muss, dann muss X das auch. Was dazu führt dass selbst die "wenigen" Resourcen die man deterministisch finalisieren möchte zu viel Aufwand führen.

    Aus dem Grund fände ich wichtig hier Support von der Sprache zu haben.

    Die fast schon "kanonische" Lösung in Java (und C# und ...) ist das Problem ab einem gewissen Punkt einfach zu ignorieren. Das kanns dann aber auch irgendwie nicht sein. Ich ärgere mich jedesmal wenn ich das dumme Visual Studio zu machen muss, nur weil irgendwo noch ein Handle auf irgendein Verzeichnis rumhängt, in dem ich vor Stunden mal drinnen ein Projekt offen hatte. Mit dem Effekt dass ich das Verzeichnis nicht löschen kann solange das Studio offen ist. Und solche Fehler sind nicht die Ausnahme, sondern eher die Regel.

    Aus dem Grund fände ich wichtig hier Support von der Sprache zu haben.
    (ja, ich weiss dass ich den Satz 1:1 so oben schon stehen habe)

    ----

    Es müsste doch irgendwie möglich sein beides unter einen Hut zu bringen, also billige & nicht deterministische Collection für die Klassen wo es OK ist, und teurere, dafür deterministische Finalisierung für Klassen wo es wichtig ist.

    Die Collection könnte ja unverändert bleiben, dass der rohe Speicher bis zur nächsten Collection stehen bleibt stört ja keinen. Zusätzlich müsste es aber einen Mechanismus geben, der bestimmte Klassen deterministisch finalisiert. Dabei sollte auch sichergestellt sein dass wirklich keine Referenzen auf die jeweiligen Objekte mehr existieren. Was gleich der nächste Punkt ist: die "übliche" Lösung über "Close" oder "Dispose" führt dazu dass man mit Zombie-Objekten rechnen muss. D.h. jede öffentliche Methode einer solchen Klasse muss checken ob die Instanz nicht vielleicht ein Zombie ist, und falls ja eine entsprechende Exception werfen (z.B. ObjectDisposedException). Spätestens wenn man 100 solche Checks irgendwo eingebaut hat hängt es einem zum Halse heraus.

    BTW: dass deterministische Finalisierung langsam ist ist klar, allerdings bremst es ja nur analog zur Anzahl der Objekte die deterministisch finalisiert werden müssen. Da diese üblicherweise sowieso recht teuer sind sollte das IMO kein Problem sein.

    uswusf.

    @Shade Of Mine:

    Funktionale Programmierung hat IMO ein ähnliches Problem: mutable State. Auf dem Papier sieht es nett aus ohne mutable State zu arbeiten, aber es geht nicht. Die Lösungen wie dieser nachträglich irgendwo dazugepfriemelt wird sind oft grausam. Was in Java "Close" ist ist in funktionalen Sprachen mutable State (IO oder was auch immer).
    Ich sollte allerdings dazusagen dass ich ganz sicher kein Experte bin was funktionale Programmierung angeht. Und ich lasse mich gerne eines besseren belehren, falles es doch halbwegs saubere Lösungen für das "mutable State" Problem geben sollte.



  • Shade Of Mine schrieb:

    Aktuell ist die einzige Antwort die es auf die Multi-Core Problemstellung gibt: funktionales programmieren. Es gibt einfach keine andere vernünftige Antwort.

    LOL, du kannst das sagen, weil du ja jede Lösung kennst, du hast ja auch jeden Sourcecode auf diesem Planeten gesehen, nur unseren anscheinend nicht... 🙄



  • hustbaer schrieb:

    BTW: dass deterministische Finalisierung langsam ist ist klar,

    Warum sollte sie langsam sein? Entweder man muß deterministisch Finalisieren oder man muß es nicht machen. Egal welche Programmierungsprache man verwendet, die Arbeit fällt hält in unterschiedlichen Programmkonstrukten an. In C++ ist über RAII gelöst in Java gibt es viele finally Blöcke abzuarbeiten. Es scheint mir, daß hier einige inkorrekt formulierte Programme zum Vergleich heranziehen, was ein unzuverlässiger Vergleich wäre.



  • is klar schrieb:

    Shade Of Mine schrieb:

    Aktuell ist die einzige Antwort die es auf die Multi-Core Problemstellung gibt: funktionales programmieren. Es gibt einfach keine andere vernünftige Antwort.

    LOL, du kannst das sagen, weil du ja jede Lösung kennst, du hast ja auch jeden Sourcecode auf diesem Planeten gesehen, nur unseren anscheinend nicht... 🙄

    das multicore problem haengt wie ein damokles schwert ueber der software entwicklung. apple hat zB fuer das neue mac os x einen feature freeze ausgerufen und ueberarbeiten jetzt die architektur fuer multi cores.

    es ist ein ziemliches problem im moment. die ghz zahlen bewegen sich nicht und die ersten consumer pcs haben 4 cores. mit nehalem werden 16 logische cores einzug in den consumer bereich erhalten.

    wie nuetzt man diese aus? jede software plattform entwickelt mit hochturen an loesungen. bis her kam nur funktionale programmierung als loesung daher. und das ist nicht zufrieden stellend. ms geht den weg der integration von funktionalen komponenten in .net -> parallel.for und plinq. bei java hat sich noch nichts ausgezeichnet, bis auf java.util.concurrent und futures sind schon nicht uninteressant, aber es fehlt etwas. was apple zeigen wird, wird man auch noch sehen.

    aber aktuell gibt es keine bessere antwort als funktionale programmierung. damit umgeht man eine menge der probleme. da man damit aber massig legacy code wegschmeissen muss, ist es keine tragbare loesung...



  • Shade Of Mine schrieb:

    aber aktuell gibt es keine bessere antwort als funktionale programmierung.

    Doch es gibt eine bessere Antwort darauf, ein besseres Prozessordesign. Intels x86 sind extrem schlecht auf Multithreadabarbeitung ausgelegt. IBM macht das mit den Power 6 MCM sehr viel besser. Natürlich bleibt hier das Problem der Nebenläufigkeit bestehen, aber je größer die Kommunikationsbandbreite ist desto weniger signifikant ist das Problem.


Anmelden zum Antworten