Warum Java vom Prinzip her schneller als C++?


  • Mod

    Manuelh87 schrieb:

    und sag mir dann bitte wie mich dann das java programm überholen will. also wie ein java programm aussieht, dass IMMER schneller als ein vergleichbares c++ programm ist??

    Ich habe schon ziemlich weit vorne in diesem Thread etwas bezüglich solcher Aussagen gesagt. Ich habe zum Beispiel einen Bereich genannt, in dem C++ nicht optimieren kann, Java aber prinzipiell schon: Das betraf das Inlining bei vorliegender Laufzeitpolymorphie. Stell dir einen Algorithmus vor, der aus verschiedenen Bausteinen zusammengesetzt ist, die zur Laufzeit zusammengefügt werden. Für jeden Baustein gibt es eine abstrakte Basisklasse oder ähnliches und mehrere konkrete Klassen, die die geforderte Funktionalität dieses Bausteins auf unterschiedliche Weise realisieren. Stell dir weiter vor, dass dieser Baustein in einer Schleife genutzt wird, die sehr oft durchlaufen wird. C++ könnte da dann kein Inlining betreiben, da es zur Compilezeit nicht die Informationen zur Verfügung hat, welche konkrete Realisierung da wann gebraucht wird. Der Hotspot-Jitter hat diese Informationen und könnte somit entsprechendes Inlining betreiben. Solche konfigurierbaren Algorithmen setze ich im Übrigen sehr sehr häufig ein.

    Naja... soweit zur Theorie. Wie es wirklich aussieht, habe ich ja auch weiter oben geschrieben. Sowohl in C++ als auch in Java kommt man nicht ans Optimum heran. Insofern ist das eine Phantomdiskussion. Man sollte eher von mal zu mal testen, ob eine gegebene Technologie die Anforderungen für ein bestimmtes Projekt erfüllt oder nicht. Allgemeine Aussagen sind da eher mit Vorsicht zu genießen.

    ...ach ja: Bevor hier wieder einer kommt mit: "Mit C++ kann man da auch optimieren, weil man mit C++ ja ne VM schreiben kann...". Dann würde man so weit gehen, dass man sich eine neue Sprache schafft und letztendlich landet man dann wieder bei etwas wie Java oder C# oder so. Die JVM von Sun ist ja auch in C++ geshreiben, trotzdem sagt man zu Java Java und nicht "modifiziertes C++" oder so.



  • Manuel87! Der JIT von Java compiliert nicht zu Anfang des Programmstart, sondern zur Laufzeit (Just in Time!) entscheidet er, was und vorallem wie er kompiliert. Ein sehr einfaches Beispiel:

    switch(i) {
     case 0:
        blabla;
        break;
     case 1:
        blabla;
        break;
    }
    

    So, wenn der JIT an die gezeigte Stelle kommt, führt er diese normal aus. Er merkt sich aber wie das Ergebnis war. Z.B. das case 1 eingetreten ist. D.h. case 1 wird wahrscheinlich öffters als case 0 betroffen sein. Beim nächsten Durchlauf dieser Stelle wird er das ganze in Maschinencode kompilieren, aber mit dem UNterschied, das case 1 vor case 0 geschoben wird. Weil so brauch die CPU weniger Vergleiche machen, da case 1 wahrscheinlich öffters bei dem switch zutreffen wird.

    Das ist jetzt so einfach mal von mir und meiner Vorstellung des JIT. Wenn das Java nicht machen würde, wäre Java noch langsamer. :p 😃

    Jetzt sagen sicherlich die Java-Fans: Ätsch! Wir werden dadurch C++ einholen.

    Da sage ich nur: Ätsch! Für C++ gibts das heute auch schon, wenn auch nicht zur Laufzeit beim Endanwender. Aber das PGO (Profile Guided Optimazation) vom VisualC++ 2005 Compiler macht genau das beim Entwickler! Vorgehensweise:

    1. Release Build erstellen, mit aktivierten PGO.

    2. Das fertige Kompilat wird jetzt vom User einmal laufen gelassen. Bei einer Server-Software wird dann halt der Server einmal laufen gelassen. Oder bei einem Spiel, wird halt ein paar Sekunden gespielt, damit z.B. die 3D-Engine einmal alles mögliche dargestellt hat. In der Zwischenzeit macht PGO eine Statistik, z.B. über die oben genannten Switch-Fälle. Halt alles das was statistisch zur Laufzeit optimert werden könnte.

    3. Mit diesen gewonnen Infos wird dann einfach ein optimierter Build erstellt. Und schon hat man einen Code der auch Laufzeit-Optimierung enthält.

    Laut Microsoft hat das neukompilieren ihres SQL Servers 2005 allein nur durch die neue PGO-Funktion den Server im Schnitt 20-30% schneller gemacht!



  • Gregor schrieb:

    ...ach ja: Bevor hier wieder einer kommt mit: "Mit C++ kann man da auch optimieren, weil man mit C++ ja ne VM schreiben kann...". Dann würde man so weit gehen, dass man sich eine neue Sprache schafft und letztendlich landet man dann wieder bei etwas wie Java oder C# oder so. Die JVM von Sun ist ja auch in C++ geshreiben, trotzdem sagt man zu Java Java und nicht "modifiziertes C++" oder so.

    hab mir schon gedacht das du das nicht verstehen wirst. ich mein ja nur deine so hochgelobten algos der verbesserung könnten ja trotzdem in einem c++ programm ebenfalls miteingebracht werden könnten...

    das mit der basis klasse ist ja schön und gut... und warum funktioniert das jetzt in c++ schlechter?? wenn dich die virtual calls stören dann kannst du die natürlich auch mit ein paar kniffen umgehen, sodass nur ein virtueller call benötigt wird... es liegt alles bei dir als c++ coder...
    aber um soetwas einzusehen muss man halt auch ein hardware-nahes vertändniss haben... ist ja schön das du theoretisch weißt wie gesagt wird dass die jVM etwas umsetzt.
    Es gibt soo viele möglichkeiten genau dieses verhalten, welches du ja so toll findest, in c++ selbst zu machen und zu verwenden... man muss halt dabei nachdenken.. aber das ist ja nicht negativ, oder?

    mfg Manuel



  • Artchi schrieb:

    Manuel87! Der JIT von Java compiliert nicht zu Anfang des Programmstart, sondern zur Laufzeit (Just in Time!) entscheidet er, was und vorallem wie er kompiliert. Ein sehr einfaches Beispiel:

    switch(i) {
     case 0:
        blabla;
        break;
     case 1:
        blabla;
        break;
    }
    

    So, wenn der JIT an die gezeigte Stelle kommt, führt er diese normal aus. Er merkt sich aber wie das Ergebnis war. Z.B. das case 1 eingetreten ist. D.h. case .....

    aha... weißt du wie ein guter c++ compiler das umsetzt??
    ein vergleich ob der index in range liegt, und dann ein jump table... 😮 na da stauenen die java fanatiker...
    Und um die reihung richtig zu haben... halt bei ifs... ja sry, aber wer schreibt den das programm?? du wirst ja wohl selber wissen welcher case wahrscheinlicher ist... völlig unnötig da einen auslastungstest zu machen...

    im gegenteil: jetzt mach ich als kleiner fetter java coder eine funktion und stell bewusst ein case for das andere weil ich diese reihenfolge bevorzuge (gehen wir mal davon aus das switch case als cmp umgesetzt wird) weil der code dahinter öfter aufgerufen wird. so jetzt ist aber das erste case das andere und die JVM schiebt jetzt das ganze in die falsche reihenfolge und kompiliert das dann, nach deinem schema...? oder vielleicht doch nicht??

    -> wo ist jetzt die große verbesserung durch die JVM??
    mfg manuel



  • JBeni schrieb:

    Ein Programm, dass auf einmal und ohne brauchbare Kontrolle des Benutzers große Mengen Rechenleistung anfordert, kann nicht Problem des Betriebsystems sein.

    Ok, hier sollte man differenzieren: wenn mehrere Programme laufen und eines klaut den anderen Rechenzeit, dann ist das OS schlecht (*hüstel* kann man immerwieder schön bei Windows beobachten...).
    Wenn es programmintern abläuft, ists natürlich was anderes.

    Kein OS kann mehr Rechenzeit/Zeiteinheit liefern, als die Hardware liefern kann. Das Umkopieren von großen Speicherblöcken kostet Rechenzeit und die GC fragt nicht beim OS an, ob jetzt ein richtiger Zeitpunkt wäre und kann auch nicht warten, weil sonst Java nicht weiterlaufen würde.

    JBeni schrieb:

    JBeni schrieb:

    Über die seltsam unflexible, problemverursachende, unangepasste Pseudo-Verwaltung von Speicher bei der JVM, möchte ich mich lieber ausschweigen...

    Warum? Reden ist Silber, Schweigen ist Gold?

    Das System ist IMHO der grösste Nachteil der JVM, deshalb schweige ich.

    Da stichel ich noch ein wenig... 😉
    Das wichtigste Merkmal von Java ist die JVM und die JVM ist der größte Nachteil von Java. Damit ist das wichtigste Merkmal von Java ein Nachteil, wenn ich das grade richtig verstehe!?

    JBeni schrieb:

    95% * (10% Systeme die überhaupt Linux haben) * (10% Die dieselbe Software auf beiden Systemen benötigen) = verschwindend gering 😉

    Mich würde mal die Quote interessieren, wenn man die ganzen Gamer und LAN-Party-Gänger abzieht, die vermutlich keine Java Spiele zocken...
    Diese Systeme sind schließlich keine Computer, sondern Spielzeuge. Waschmaschinen enthalten ebenfalls Computer, werden aber in der Statistik auch nicht geführt, sonst wäre die Zahl der Dualboot-fähigen Systeme vermutlich verschwindet gering. ^^

    JBeni schrieb:

    Stimmt. Aber wo ist das Problem - weigern sich Programmierer bzgl. GUI-Frameworks dazuzulernen?

    Hoffentlich nicht *g*. Aber man kann ein Framework nicht in einem Tag kennen lernen. Wenn dann Wochen auf kennen lernen + coden + debuggen + etc. draufgeht ist das nicht so dolle.

    Hmm.. wie sollte man sonst das Know-How steigern, dass die Firma anbieten kann?

    JBeni schrieb:

    Wenn ich dem was von Java erzählen würde, der würde mich fragen, warum er nicht gleich PHP nehmen soll.

    Mein Kollege hat sich letzhin ein neues Visual Studio besorgt. Er fluchte gottsjämerlich, dass nichtmal der Code geschrieben im Vorgänger kompilierte...

    Dann rate ich dringend zu ein paar Erfahrungen in PHP3, PHP 4, PHP 4.3 und PHP 5.
    Selbst Microsoft kann das nicht derart verbocken, obwohl die Unterschiede zwischen VC6 und VC 2003 gravierend sind. Positiv in der IDE, zurückhaltend bzgl. des Sourcecodes.

    JBeni schrieb:

    Ich konnte also mitten in der Projektentwicklung die Version wechseln.

    Meinen Compiler übertrage ich ohne Änderungen zwischen GCC 2.95, GCC 3.3, GCC 4.0 und StormC.
    Visual C habe ich nicht ausprobiert, da mich Windows nicht so anspricht.

    JBeni schrieb:

    Java 1.6 hat GARANTIERT ein Schlüsselwort, um Klassen zu verschachteln und alle werden jubeln und sagen 'Java ist die inovativste Sprache der Welt' und diejenigen, die C++ programmieren, werden wieder mal freundlich lächeln und sich einen grinsen.

    Hr, braucht es nicht. Gibt es schon seit Java 1.2 (oder wars 1.1?). Das nennt sich innere, anonyme oder Methodenklasse (Klassen kann man direkt in einer Methode definieren. War ziemlich überrascht, als ich das bemerkte).
    Java 1.6 wird (wie immer) Erweiterungen der Standardlib haben, der Syntax wird nicht verändert.

    Nix inline definiert....

    class foo
    {
      int x;
      int y;
      /* .. */      
    };  // 40 Bytes groß...
    
    class bar
    {
      short  Pad;
      foo *  ZeigerAufFoo;             //  4 Bytes groß
      foo    VerschachteltesElement;   // 40 Bytes groß      
    };  // 44 Bytes
    
    class snafu
    {
      int    Pad;                      // 4 Byte
      foo    SnafuEnthaeltEinFoo;      // 40 Byte
      bar    UndEinBar;                // 44 Byte
    }: // 88 Byte
    

    Um auf VerschachteltesElement zuzugreifen, muss nicht teuer referenziert werden:

    void blah( void )
    {
      bar baz;  // Wobei baz auf dem Stack an Adresse 4711 liegt
    
      baz.ZeigerAufFoo = new foo();     // Neues Foo anlegen bei 0815 => bei 4713 den Wert 0815 ablegen.
      baz.ZeigerAufFoo->y = 1;          // Stackrelativ an Position 0 lesen (Baz:4711), 2 Aufaddieren (.ZeigerAufFoo:4713), dereferenziere(*():0815), dann 4 aufaddieren(.y:0819), Zuweisung durchführen(=) mit Wert 1
      baz.VerschachteltesElement.y = 1; // Stackrelativ an Position 0 lesen (Baz:4711), 6+4=10 aufaddieren (.Verschachteltes Element.y:4721), Zuweisung durchführen(=) mit Wert 1 ablegen
    }
    

    Die eingebetete Klasseninstanz ist also ohne Dereferenzierung erreichbar. Die Additionen (.VerschachteltesElement.y) können vom Compiler zusammengefasst werden, was nicht geht, wenn eine dereferenzierung dazwischen liegt, die bei Java grundsätzlich dazwischen liegt.
    Das könnte unser Erstsemesterstudent zum Beispiel als Argument nehmen, dass Java nicht so schnell wie C werden kann, selbst wenn es kompiliert ist, läßt sich das hier nur schwer bzw. gar nicht wegoptimieren.
    Die Zeitverzögerung wird bei vielen Problemen nicht groß auffallen, aber es bleibt dabei, dass Java bei jedem Zugriff zwei zusätzliche Takte verbrät, was in Schleifen oder vielen derartigen Zugriffen innerhalb von Schleifen sich schon zu bemerkbaren Sekunden zusammenaddieren kann.

    JBeni schrieb:

    In C++ habe ich seit 15 Jahren freie Wahl des Verkehrsmittels. Deswegen bekomme ich dann zu hören, da macht ja jeder alles, wie er will - den Sourcecode versteht dann ja kein Mensch mehr.

    Du willst sagen, du verstehst den Quellcode eines fremden C++-Programmieres beim ersten hinschauen? Hut ab, aber dafür hast du lange geübt.

    Nein. Den Code eines fremden, fähigen Programmierers verstehe ich nicht, da muss ich mich reinarbeiten.
    Da die meisten Programmierer aber nicht fähig sind, sehe ich häufig beim ersten hinschauen, die Fehler im Sourcecode.

    Ich programmiere seit 1995 C, seit 1999 C++ und davor Assembler.
    Wer debuggen will, sollte das in Assembler lernen. Man lernt zwei Dinge:
    a) Wie finde ich effizient Fehler
    b) es ist effizienter erst zu denken, dann zu programmieren. Selbst wenn man effizient Fehler findet, ist es ein tierischer Aufwand, den man sich in 90% der Fälle hätte sparen können, wenn man nicht einfach programmiert hätte nach dem Motto 'Wird schon passen'.

    JBeni schrieb:

    schreib' mir eine PM

    Funktioniert in diesem Forum nicht. 😕

    Wenn Du mir schreiben möchtest, wirst Du meine E-Mail-Adresse sicherlich rausfinden.
    Ansonsten: fnfpun@ngebcf.pbz
    Rot13 ist Dein Stichwort.

    Haskell-Tutorial: Thx.



  • Artchi schrieb:

    Manuel87! Der JIT von Java compiliert nicht zu Anfang des Programmstart, sondern zur Laufzeit (Just in Time!) entscheidet er, was und vorallem wie er kompiliert. Ein sehr einfaches Beispiel:

    switch(i) {
     case 0:
        blabla;
        break;
     case 1:
        blabla;
        break;
    }
    

    So, wenn der JIT an die gezeigte Stelle kommt, führt er diese normal aus. Er merkt sich aber wie das Ergebnis war. Z.B. das case 1 eingetreten ist. D.h. case 1 wird wahrscheinlich öffters als case 0 betroffen sein. Beim nächsten Durchlauf dieser Stelle wird er das ganze in Maschinencode kompilieren, aber mit dem UNterschied, das case 1 vor case 0 geschoben wird. Weil so brauch die CPU weniger Vergleiche machen, da case 1 wahrscheinlich öffters bei dem switch zutreffen wird.

    Das ist jetzt so einfach mal von mir und meiner Vorstellung des JIT. Wenn das Java nicht machen würde, wäre Java noch langsamer. :p 😃

    Ich habe keine Ahnung, was die JVM alles macht, aber wenn sie das macht, was Du hier grade vorschlägst, dann sollten wir Java erst recht nicht ernst nehmen.

    void * SwitchTable[] { CASE_0, CASE_1 };
    
       goto SwitchTable[i];
    
    CASE_0:
       blabla;
       goto EXIT;
    
    CASE_1:
       blabla;
    
    EXIT:
       ...
    

    Hast Du eine Vorstellung, wieviel Zeit es kostet, erstmal rumzuraten, was ich dann kompilieren könnte, nur um ein popliges If-zu sparen?
    Switch ist schneller, weil es eben nicht durch x-Fälle durchgehen muss, deswegen darfst Du auch kein case 3 && j == 5: angeben.
    Ob das da oben von einem C-Compiler akzeptiert wird, weiß ich nicht. Das ist nicht mein üblicher Programmierstil, jedenfalls nicht in C. Das vielleicht am Rande...

    Artchi schrieb:

    Jetzt sagen sicherlich die Java-Fans: Ätsch! Wir werden dadurch C++ einholen.

    Da sage ich nur: Ätsch! Für C++ gibts das heute auch schon, wenn auch nicht zur Laufzeit beim Endanwender. Aber das PGO (Profile Guided Optimazation) vom VisualC++ 2005 Compiler macht genau das beim Entwickler! Vorgehensweise:
    Laut Microsoft hat das neukompilieren ihres SQL Servers 2005 allein nur durch die neue PGO-Funktion den Server im Schnitt 20-30% schneller gemacht!

    Was hat C++.NET mit C++ zu tun?
    Da kann ich auch gleich Java nehmen... <kopfschüttel>

    Was das Neukompiliern von SQL-Server angeht, so sage ich Dir, dass das vor allem darauf hinweist, dass von den Programmierern, die die ursprüngliche Version von SQL Server 2005 geschrieben, keine mal seinen Verstand beim Programmieren benutzt hat. Wenn man einer Maschine soviel Phantasie einbauen kann, dass sie sich Gedanken darüber machen kann, welcher Fall häufiger eintritt, dann waren die Programmierer ziemlich hohl, weil die sollten das wissen, bevor sie anfangen zu programmieren.



  • Der PGO ist meines Wissens für natives C++ und nicht C++/CLI!

    Ich weiß nicht was alle auf diese Laufzeitoptimierung rumhacken? Naja... Und das switch-Case-Beispiel war nur ein Beispiel, ob es ein JIT oder PGO wirklich macht, weiß ich nicht. Es war nur ein einfaches Beispiel, wie ich es mir vorstelle. Und selbst wenn es wirklich so ist, fänd ich es toll und nicht schlecht. Denn 30% Performance-Gewinn ist mir egal wo die herkommen, hauptsache ich hab die.

    Was hat Bjarne Stroustrup mal geschrieben? "Es geht nicht darum seine 5 coolsten Zeilen Code zu schreiben!" Aber hier reden viele, als ob sie die coolsten Zeilen code schreiben wollen. Hobby-Coder können das gut und gerne machen, da hat man die Zeit, aber nicht im harten berufsleben.

    Manuel87 sagt mir schon alles: Jahrgang 87. Als ich Schüler war, hab ich auch nur coole Sachen programmiert.



  • c++ macht das 1) und zweitens... belästigt mich da nicht nur weil ihr zu faul seit euch die info aus dem netz zu ziehen... wenn ihr mitdiskutieren wollt dann wärs vielleicht klug sich mal anzusehen wie machne switch case sachen vom compiler versucht werden umgestetzt zu werden (was ned immer geht)

    also ich erkläre:

    vorallem bei enums wie enum State {state_running, state_down, state_error, state_otl, state_abc, ...};
    also ohne expliciten zahlen geht das besser..

    so nun probieren manche compiler
    das hier zu erreichen:

    void funktion (State mystate)
    {
      if(mystate isnot in range)
        goto default;
      else
        goto jumptalbe[mystate];
    }
    

    also so ungefähr... also genau eine abfrage (oder 2 von mir aus) und alle weitern case'es werden gleichschnell und gut ausgeführt... und man sparrt jedemenge cmp die ja langsamer sind...



  • UNd was passier bei String-Vergleiche? Und was ist wenn die Werte nicht sequenziell sind? (1, 2, 3 usw.) sonder z.B. über weite Abstände: 1, 20, 3000, 400000? Funktioniert das dann noch mit ner Jumptable? Ich meine nur, schön und gut das es eine jmp-Table für primitive Datentypen gibt.



  • Artchi schrieb:

    Der PGO ist meines Wissens für natives C++ und nicht C++/CLI!

    Ich weiß nicht was alle auf diese Laufzeitoptimierung rumhacken? Naja... Und das switch-Case-Beispiel war nur ein Beispiel, ob es ein JIT oder PGO wirklich macht, weiß ich nicht. Es war nur ein einfaches Beispiel, wie ich es mir vorstelle. Und selbst wenn es wirklich so ist, fänd ich es toll und nicht schlecht. Denn 30% Performance-Gewinn ist mir egal wo die herkommen, hauptsache ich hab die.

    Wenn ich bei Saturn 30% unter der UVP kaufe finde ich das auch toll.
    Ich bin selten Kunde bei Saturn. Ich kaufe lieber 10% unter dem Saturnpreis.

    Artchi schrieb:

    Was hat Bjarne Stroustrup mal geschrieben? "Es geht nicht darum seine 5 coolsten Zeilen Code zu schreiben!" Aber hier reden viele, als ob sie die coolsten Zeilen code schreiben wollen. Hobby-Coder können das gut und gerne machen, da hat man die Zeit, aber nicht im harten berufsleben.

    Manuel87 sagt mir schon alles: Jahrgang 87. Als ich Schüler war, hab ich auch nur coole Sachen programmiert.

    Das Zitat ist unpassend angebracht und soweit ich weiß, würde Stroustrup das in diesem Zusammenhang auch nicht sehen wollen.
    Programmiersprachen sind Grundlagen. Da geht es nicht um die 5 coolsten Zeilen. Nur eine versaute Zeile versaut alle Programme, da müssen alle Zeilen "cool" sein.
    Bei Anwendersoftware stimme ich Stroustup zu.

    Wenn sich jemand als Jugendlicher Gedanken darüber macht, wie man "cool" programmiert, finde ich das besser, als wenn mans nie lernt.
    Wer's einmal gelernt hat, hat auch im Altern noch ohne PGO 30% Performance Gewinn im Preis inklusive.

    Ich habe mit 19 auch noch Prozessortakte gezählt. Schade, dass das heute keiner mehr macht.



  • Artchi schrieb:

    UNd was passier bei String-Vergleiche? Und was ist wenn die Werte nicht sequenziell sind? (1, 2, 3 usw.) sonder z.B. über weite Abstände: 1, 20, 3000, 400000? Funktioniert das dann noch mit ner Jumptable? Ich meine nur, schön und gut das es eine jmp-Table für primitive Datentypen gibt.

    Hashtables, Suchbäume... es gibt soviele Möglichkeiten da 'nen Turbolader dazuzupacken.
    [Bevor die nächste Frage kommt, die Bäume sind wie die Switch-Anweisung konstant und werden nicht zur Laufzeit erstellt...]

    In C++ vergleicht kann man keine Strings mit switch/case vergleichen, hier würden Adressen verglichen.



  • Artchi schrieb:

    Ich weiß nicht was alle auf diese Laufzeitoptimierung rumhacken?

    du siehst das falsch... ich lass euch java leuten ja eure laufzeitoptimierung.. soll es eure miesßen codes doch mieß optimieren (übertrieben!!! ⚠ )
    nur wenn sich dann mieße coder kommen und mießen code in java und in c++ schrieben und dann feststellen das der java code wegen dieser tollen optimierung besser ist dann kommt mir nunmal das kotzen...
    hab ja schon gesagt das java druchaus seine berechtigung hat... aber eben nicht im sektor performance... denn dieser sektor gehört eben anderen. Das wäre wie wenn ich jetzt plötzlich anfangen würd dass c++ doch eigentlich viel portabler als java ist und dann ein beispiel nehme, dass halt aus gründern der schlechten implementierung auf einem betreibssystem der VM von java einen error hat und dann sagen würde: "ja mit c++ muss ichs zwar compilieren aber es funktioniert.." bei dem ausruf "c++ ist also portabler als java" würdet ihr euch ja auch aufregen oder?

    Artchi schrieb:

    Naja... Und das switch-Case-Beispiel war nur ein Beispiel, ob es ein JIT oder PGO wirklich macht, weiß ich nicht. Es war nur ein einfaches Beispiel, wie ich es mir vorstelle.

    Genau das ist das problem; du weißt nicht was JVM macht aber du meinst weil sie beschreiben es sei so toll kann es mal aufjeden fall c++ besiegen... genau aus dem grund ^^ diskutieren wir hier überhaupt.

    Artchi schrieb:

    Aber hier reden viele, als ob sie die coolsten Zeilen code schreiben wollen. Hobby-Coder können das gut und gerne machen, da hat man die Zeit, aber nicht im harten berufsleben.

    Naja ist schon klar, nur fänd ich es angebracht, sich soweit zu informieren, dass man schon halbwegs das optimum herausholen kann... denn anwender fragen sich dann wieder, warum ich einen p4 mit 2 ghz brauch um ein textverarbeitungsprogramm sinnvoll betreiben zu können ( ⚠ übertrieben)

    Artchi schrieb:

    Manuel87 sagt mir schon alles: Jahrgang 87. Als ich Schüler war, hab ich auch nur coole Sachen programmiert.

    Dann würd ich sagen "back to the roots!"

    Anscheind hast du dich aber nicht versucht mit solchen sachen genauer auseinanderzusetzten (z.b. wie funktioniert das ganze wirklich... usw... cpu, asm lesen/schreiben, mit dem disasm anwendungen auseinandernehmen)

    schön wärs wenn ich nur coole codes hätte... das kannst mir glauben. Das man im berufsleben wenig chance mehr hat sich da so toll darum zu kümmern ist mir schon klar... aber wie gesagt, ihr java fans habt die diskussion angebrochen, nicht ich. Dann behauptet nicht sachen die nicht so sind, warum ihr keine zeit habt euch damit zu beschäftigen ist doch egal, wenn ich nicht weiß wies wirklich ist, dann kann ich doch nicht so einen fixen standpunkt vertreten.

    Nochmal: Java hat ja seine Berechtigung. Niemand sagt was gegen java.

    mfg Manuel



  • Ich habe mit 19 auch noch Prozessortakte gezählt. Schade, dass das heute keiner mehr macht.

    Ich dachte wenigstens an der FH versuchen sie das einem auszureden. Offenbar nicht, wir leben weiterhin in einer kleinkarierten Programmierwelt. Es geht nämlich gar nicht so sehr um das optimalste Ergebnis für einen kleinen Teil sondern um die Abbildung und Abstraktion eines Gesamtsystems am Computer. Der Tag wird kommen an dem wir dem Computer nur noch unser Modell mitteilen und es wird überhaupt kein Programmiercode mehr benötigt. Programmieren ist ja eigentlich ein besseres Handwerk das jeder erlernen kann. Trotzdem denkt der Programmierer immer er sei weiß ich was besonders wichtig. Dabei ist das einzig wichtige ein möglichst gut designtes Modell zu haben. Wenn das drei Takte pro Durchlauf mehr kostet ist das in erster Linie mal schnurz egal. Man stellt einen zweiten Server auf der in der heutigen Zeit sowieso nichts kostet und aus fertig. Es soll Anwendungsbereiche geben wo man (weil wenig Platz, weil wenig Leistung, weil sonstwas) immer noch kleinkariert denken muss, aber meistens ist es umsonst. Da gibts Leute die schreiben eine Woche lang an einer Klasse und freuen sich hinterher, dass sie eine Operation mit "null-overhead" erreicht haben. Bloß leider ist die Technologie schon wieder veraltet und die Klasse braucht kein Mensch mehr. Ich hoffe innigst, dass Programmieren sehr bald endlich das ist was es ist: Eher ganz unten in der Nahrungskette. Ich habe eine Vision erstelle mit meinen Ingenieursfähigkeiten ein Modell der Wirklichkeit und speise es ein. Handwerk wird automatisiert.

    MfG SideWinder



  • Artchi schrieb:

    UNd was passier bei String-Vergleiche? Und was ist wenn die Werte nicht sequenziell sind? (1, 2, 3 usw.) sonder z.B. über weite Abstände: 1, 20, 3000, 400000? Funktioniert das dann noch mit ner Jumptable? Ich meine nur, schön und gut das es eine jmp-Table für primitive Datentypen gibt.

    Und wann brauch ich das? stichwort intelligentes design...
    In diesem fall wäre die umsetzung so wie if... also cmp's.
    Die ich aber in der richtigen reihenfolge anbringen kann, wie es java wirklich macht wissen wir ja nochimmer nicht, hat also auch keinen sinn darüber zu diskutieren... fakt ist, besser als das meist verwendete ganz nachoben zu schieben kanns auch ned machen... und das kann ich ja in c++ schon vorm compilieren so machen...
    mfg Manuel



  • @ SideWinder:
    Ja vom prinzip her sag ich ja garnichts gegen deine idee... ein gutes design (was sicher nicht jeder "erlernen kann" ist natürlich am wichtigsten... auch wenn es geringe kosten hat.

    Aber vorsicht mit der äußerung: denn das ist genau das, das ich soo lange spüren habe müssen mit meinem alten pc. Anwendungen laufen grundlos nicht gut. Warum? ja weil der programmierer ungeschickt abstrahiert hat und dann auch noch soch schlecht wie möglich gecoded hat und ja, mit dem ergebnis dieser "arbeit" hab ich mich dann als anwender herumschlagen müssen.

    Die kunst ist es gut zu abstrahieren und dazu auch noch performant zu coden. Und sag jetzt nich dass das nicht möglich ist. Sicher ist es möglich, es kann eben nur nicht jeder. Deshalb ist eben coden nicht ein einfaches handwerk sonder doch komplizierter (und wird ja auch dementsprechent entlohnt...)

    [edit:]

    und nicht immer ist ja performance wichtig.. bsp:
    hab eine tcp/ip klasse, also server und client. Da hab ich natrülich nicht probiert das optimum an performance rauszuholen, da jeder weiß dass das tcp protokoll sowieso zu langsam ist für die bereiche wo man das optimum benötigen würde... da ging es mir eher darum so zu designen, dass ich als basisklasse die ostream klassen nehmen kann und somit die aspekte der oop noch besser genutzt werden können..

    im gegensatz dazu wollte ich eine schnelle + dynamische vektor klasse für spätere spiele oder rechnereien... naja und da wurden natürlich alle tricks angewant die es sogibt (allerdings ohne inline asm).
    Da hab ich eben for schleifen geunrollt (?? weiß ned wie man dazu sagt...)
    usw... denn hier bringt es was. wenn ich die entsprechende funktion oft benötige...

    mit unroll mein ich das:

    // normaler code ... also ungefähr:
    for (int i=0; i<3; ++i)
    {
      array[i]=zahl;
    }
    
    // geunrollt:
    array[0]=zahl;
    array[1]=zahl;
    array[2]=zahl;
    

    gibt compiler die das automatisch machen... aber meiner glaub ich ned. Also hab das eh vorher getestet, da hat ers nicht gemacht...

    mfg Manuel



  • SideWinder schrieb:

    Ich habe mit 19 auch noch Prozessortakte gezählt. Schade, dass das heute keiner mehr macht.

    Es geht nämlich gar nicht so sehr um das optimalste Ergebnis für einen kleinen Teil sondern um die Abbildung und Abstraktion eines Gesamtsystems am Computer.
    Programmieren ist ja eigentlich ein besseres Handwerk das jeder erlernen kann. Trotzdem denkt der Programmierer immer er sei weiß ich was besonders wichtig.
    Man stellt einen zweiten Server auf der in der heutigen Zeit sowieso nichts kostet und aus fertig.

    Hehe, die Meinung würde ich für mich behalten, das ist so ziemlich das dümmste, was ich bisher gehört habe. Viele denken so, aber wenige sagen das so kompromisslos.

    Das Modell der Fibunacci Funktion lautet:

    f(0) = f(1) = 1;
    f(x) = f(x-1) + f(x-2);

    Die Umsetzung lautet:

    int fibunacci( int i )
    {
      if( i <= 1 ) return 1;
      else return fibunacci( i-1 ) + fibunacci( i-2 );
    }
    

    Bei ausreichend großem i ist jeder Sun-Ultra-Mega-High-End MegaCluster leider total überfordert.
    Die Dinger sind alles andere als billig und wenn ich dann einen zweiten Server dazu stelle, dann kille ich den einfach, in dem ich i um 1 erhöhe.

    Dann nimmt man einen unwichtigen Programmierer aus dem Ende der Nahrungskette, gibt dem einen C64 (fast 1MHz auf 8Bit Prozessorbreite) und der frisst mit seiner "Höllenmaschine" beliebig viele Mega-Workstations.

    Das Beispiel ist optimistisch gewählt. Im Reallife wird noch viel mehr <bösesWort> programmiert.


  • Mod

    Naja, wenn hier schon so ein Simpel-Beispiel dafür gebracht wird, wie einfach man unperformanten Code schreiben kann, dann sollte man in diesem Zusammenhang auch mal sehen, wie groß der Unterschied zwischen Sprachen wie C++ und Java bei "einfachem" Code bezüglich der Performance ist. Ich hatte da vor Jahren mal einen kleinen Benchmark mit dem Sieb des Erathostenes gemacht. ...und da ist er, einmal in C++, einmal in Java:

    gregor@linux:~/JavaProjects/Test/TestPrime> cat TestPrime.cpp
    
    #include<iostream>
    #include<time.h>
    #include <cmath>
    
    int main ()
    {
       const int end = 1000000000;
       const long startTime = (long)time(NULL);
       const int arraySize = (end >> 5) + 1;
       int sieve [arraySize];
       for (int i = 0 ; i < arraySize ; ++i)
       {
          sieve[i] = 0;
       }
       int x, y, i;
       int primes = 1;
       const int sqrtEnd = (int)sqrt((double)end);
       x = 3;
       while (x <= sqrtEnd)
       {
          if ((sieve[x >> 5] & (0x1 << (x & 0x1f))) == 0)
          {
             y = x * x;
             i = x << 1;
             ++primes;
             while (end > y)
             {
                sieve[y >> 5] |= (0x1 << (y & 0x1f));
                y += i;
             }
          }
          x += 2;
       }
       while (x <= end)
       {
          if ((sieve[x >> 5] & (0x1 << (x & 0x1f))) == 0) ++primes;
          x += 2;
       }
       std::cout << "Zwischen 0 und " << end << " liegen " << primes << " Primzahlen." << std::endl;
       std::cout << "GesamtZeit : " << ((long)time(NULL) - startTime) << " Sekunden" << std::endl;
    }
    gregor@linux:~/JavaProjects/Test/TestPrime> cat TestPrime.java
    public class TestPrime
    {
       public TestPrime ()
       {
       }
    
       public static void main (String[] args)
       {
          int end = 1000000000;
          long time = System.currentTimeMillis ();
          int [] sieve = new int [(end >> 5) + 1];
          int x, y, i;
          int primes = 1;
          int sqrt = (int)Math.sqrt((double)end);
          x = 3;
          while (x <= sqrt)
          {
             if ((sieve[x >> 5] & (0x1 << (x & 0x1f))) == 0)
             {
                y = x * x;
                i = x << 1;
                ++primes;
                while (end > y)
                {
                   sieve[y >> 5] |= (0x1 << (y & 0x1f));
                   y += i;
                }
             }
             x += 2;
          }
          while (x <= end)
          {
             if ((sieve[x >> 5] & (0x1 << (x & 0x1f))) == 0) ++primes;
             x += 2;
          }
          System.out.println ("Zwischen 0 und " + end +
                              " liegen " + primes + " Primzahlen.");
          System.out.println ("GesamtZeit : " +
                              (System.currentTimeMillis () - time) +
                               " Millisekunden");
       }
    }
    gregor@linux:~/JavaProjects/Test/TestPrime> g++ -O3 -o TestPrime TestPrime.cpp
    gregor@linux:~/JavaProjects/Test/TestPrime> /usr/java/jdk1.6.0/bin/javac TestPrime.java
    gregor@linux:~/JavaProjects/Test/TestPrime> ./TestPrime
    Zwischen 0 und 1000000000 liegen 50847534 Primzahlen.
    GesamtZeit : 37 Sekunden
    gregor@linux:~/JavaProjects/Test/TestPrime> /usr/java/jdk1.6.0/bin/java -Xmx256m TestPrime
    Zwischen 0 und 1000000000 liegen 50847534 Primzahlen.
    GesamtZeit : 41160 Millisekunden
    

    Das ist wohl ziemlich gleichwertiger Code in beiden Sprachen, der zugegebenermaßen nicht besonders viele Sprachfeatures, wie zum Beispiel viel OOP und so nutzt. Aber schauen wir uns mal den Unterschied bei diesem Beispiel an.

    Das C++ Kompilat braucht 37 Sekunden, das Javaprogramm 41. Das C++-Programm ist hier also etwa 10% schneller. ...hui, das bewegt die Welt und sollte in jedem Fall der entscheidende Faktor bei der Wahl der Programmiersprache sein, heh? 😃 Naja, glaube nicht. Aber um es mal auf den Punkt zu bringen: Hier ist Java offensichtlich nicht bedeutend langsamer. Wo ist es das denn dann? In welchen Anwendungsgebieten muss man Dinge von Java nutzen, die das Programm unnötig ausbremsen. Wenn die Leute hier andauernd sagen, wie lahm Java ist, dann sollten sie das ja auch belegen können. ...oder habe ich da aus Versehen eine Bremse in das C++ Programm eingebaut und das schafft die Aufgabe normalerweise in 5 Sekunden? Glaube nicht, aber ich kenne C++ auch nicht wirklich. Also: Zeigt mal, wo Java lahm ist.


  • Mod

    Xin schrieb:

    Dann nimmt man einen unwichtigen Programmierer aus dem Ende der Nahrungskette, gibt dem einen C64 (fast 1MHz auf 8Bit Prozessorbreite) und der frisst mit seiner "Höllenmaschine" beliebig viele Mega-Workstations.

    ...und das kann er nicht deshalb machen, weil er besonders gut C++ oder Assembler oder Java oder sonstwas kann, sondern weil er denken kann (...oder weil er aufgepasst hat, als es in der Uni beim Thema Rekursion/Iterative Verfahren das typische Fibonacci-Beispiel gab). Das ist also ein ganz wunderbares Beispiel dafür, dass die Programmiersprache bezüglich der Performance nicht so relevant wie der Programmierer ist. Die Wahl der Programmiersprache ändert nicht die zeitliche Komplexität der gewählten Algorithmen.



  • Gregor schrieb:

    Naja, wenn hier schon so ein Simpel-Beispiel dafür gebracht wird, wie einfach man unperformanten Code schreiben kann...

    [Code...Benchmark]

    Das C++ Kompilat braucht 37 Sekunden, das Javaprogramm 41. Das C++-Programm ist hier also etwa 10% schneller. ...hui, das bewegt die Welt und sollte in jedem Fall der entscheidende Faktor bei der Wahl der Programmiersprache sein, heh? 😃 Naja, glaube nicht. Aber um es mal auf den Punkt zu bringen: Hier ist Java offensichtlich nicht bedeutend langsamer.
    Also: Zeigt mal, wo Java lahm ist.

    Hmm... kann es sein, dass Du die letzten Seiten Postings gar nicht gelesen hast und Dein Posting daher voll am Thread vorbeigeht?
    Nur so ein Gedanke... kann auch sein, dass ich nicht bemerkt habe, auf welches Posting Du Dich beziehst.

    Aber... wenn Du unbedingt ein Benchmark diskutieren möchtest...
    Welches Deiner beiden Programme verbrauchte effektiv mehr Speicher, um das Ergebnis zu produzieren?

    Es ist unsinnig, mit Java gegen C/C++ anstänkern zu wollen, weil Java in diesen Disziplinen immer den kürzeren ziehen wird. Die Frage, wo Java langsamer ist, hast Du mit Deinem Benchmark selber belegt. 4 Sekunden zu ignorieren, bedeutet nicht, dass es gleich schnell ist. Insbesondere bedeutet es, dass Java nicht erste Wahl ist, wenn es um Resourcen geht, dein Dein Benchmark belegt ja, dass C++ schneller ist und damit in Deiner Fragestellung 1. Wahl.
    Das dann als Erfolg verkaufen ist dann doch eher amüsant.

    Wenn Du Java magst, was Dein gutes Recht ist, erfreue Dich an den Vorteilen der reichhaltigen Standardbibliotheken, die Dir als Java-Entwickler teilweise schnellere Ergebnisse liefern, aber versuch bitte niemanden zu überzeugen, dass Java bzgl. Resourcenverbrauch mit C/C++ mithalten könnte. Das wird immer nach hinten losgehen.

    10% kann den Unterschied machen, ob ich einen zusätzlichen Server kaufen muss oder nicht und alle Folgekosten dazu tragen muss, die nicht erforderlich wären, wenn das Programm 10% schneller laufen würde. Wenn der Mehrverbrauch an Speicher dazukommt, entscheidet sich das evtl. noch schneller gegen Java.
    Bei Aufgaben, die 10 Tage Rechenleistung fordern, sind 10% ein Tag. Das bedeutet hier, dass die vom Ergebnis abhängigen Arbeitnehmer einen Tag früher Ergebnisse haben und weiterarbeiten können. Die Rechenanlagen sind in der Regel auch nicht billig. Wenn die 10% mehr erledigen können, erzeugen die Rechner auch 10% mehr Ertrag. Wenn ein BWLer 10% mehr Ertrag hört, wird der Dir sagen, mit welcher Sprache Du ein echtes rechnerisches Programmierproblem zu lösen hast.

    Wenn Du also von Deinem privaten Interesse an Primzahlen mal wegrückst, wirst Du vielleicht erkennen, dass es nicht nur HeimPCs und Anwendungsprogrammierung gibt, wo "nur" ein Privatmensch etwas kostenlose Freizeit verliert, weil er 10% länger vor dem Computer warten muss und sich ja 'ne neue CPU kaufen kann. Kostet heute ja nix mehr.
    Angenommen jeder hätte einen Rechner, dann wären das hier rund 800 CPUs. An meinem Schreibtisch stehen 3 Rechner. Aber Kostet ja nix mehr.

    Als Privatmensch mache ich gelegentlich Bild- und Videobearbeitung. Da interessieren mich 10% auch als Privatmensch schon, entsprechend kaufe ich das Produkt, dass schneller rechnet.



  • du musst auch die auslastung usw... dazunehmen.. der benchmark zeigt nicht wirklich was... nochdazu steht auch nicht mit welchem compiler und wie optimiert wurde... das spiel ja alles eine rolle... würds ja selbst testen, aber hab keinen java compiler. Hast du java als exe compiliert oder ganz normal mit der virtual maschine laufen lassen?? denn man kann auch eine exe erzeugen (bei msj++ zum beispiel)..

    Zeig mir einen java compiler der frei ist und den ich verwenden kann und ich zeigt dir wie das ergebniss mit nem guten c++ compiler und den besten einstllungen aussieht... dann geh ich doch von mehr als 10% unterschied aus... unter umständen.

    Außerdem sagt ja niemand das du nicht java verwenden sollt und darfst. Nur probiert mit bitte nicht zu erklären dass java c++ überholt weil es Runtime-optimieren kann.. das ist BLÖDSINN.
    Warum hab ich ja schon erklärt...

    [edit]
    @Gregor:
    dein code für c++ ist fehlerhaft... muss noch schauen warum... aber er ist es.
    der code ist leider recht kompliziert (shifts) weiß ned wielange das dauern wird...

    [edit]
    naja war nicht fehler haft aber naja bisl viel am stack... hab das mal ausgelagert also heap...

    mfg Manuel


Anmelden zum Antworten