Java vs. C. Performance-Vergleich



  • HereIGo schrieb:

    Wird interessant, ob der Java Compiler shoot inlined und merkt, dass er kein Point erstellen muss.

    Anscheinend ist das der Fall! 😮 😮 😮
    War es nicht so, daß Java eine Exception schmeißen muß, wenn es integer-Überläufe gibt? Die würden vielleicht das Bißchen mehr an Laufzeit erklären. Kann mir kaum vorstellen, daß new nebst Garbage-Collection so billig ist. Ok, new ist sehr billig, klar. Oder war genug Speicer da, daß kein gc-Lauf überhaupt nötig war?

    Naja, prinzipiell ist es möglich, einen Optimierer zu schreiben, der erkennt, daß gar kein Point erstellt werden muß. Und prinzipiell ist es möglich, einen Optimierer zu schreiben, der erkennt, daß da noch keine Überläufe entstehen können. Wir messen hier nicht Sprachen aus, sondern nur derzeitige Implementierungen.

    Ich hatte vermutet, Jave würde abkacken. Das ist nicht der Fall. 100% mehr ist nichts. Diese langsamen gefühlten Java-Oberflächen haben weit mehr als 1000%. Also daran lag es wohl nicht. Aber am Code liegt es auch nicht, mag ich meinen. Was ich da so gelesen habe, war einfach, zielstrebig, offensichtlich richtig, elegant und bescheiden, offensichtlich schnell. Ich würde mir wünschen, C++-Programmierer würden so gut coden. Warum Java-Anwendungen so unglaublich oft endlos lahm sind, mir ist es ein Rätsel.

    ps: Bitte immer mit -march=native testen. Der Java-Jitter darf ja auch den Prozesssor kennen.



  • Steffo: Kannst du mal die final aus dem Point raus machen und schauen, ob das was ändert?



  • Ich habe mal dem Pi-Konstruktor 100000 als Parameter übergeben, wobei sowohl bei der C++- als auch bei der Java-Version Blödsinn rauskommt (es kommt kein PI, sondern eine Zahl kleiner 0 raus):

    [steffo@localhost performance]$ time ./pi-cpp
    -1.003
    
    real	4m19.205s
    user	4m18.967s
    sys	0m0.114s
    
    [steffo@localhost performance]$ time java Main
    -1.0029964730543903
    
    real	6m40.989s
    user	6m41.627s
    sys	0m1.991s
    

    ps: Bitte immer mit -march=native testen. Der Java-Jitter darf ja auch den Prozesssor kennen.

    Das mache ich extra nicht. Weshalb? Zeig mir mal Software, die auf diese Weise kompiliert wird. Das wird man in der Praxis kaum finden. Die Software, die auf deinem Computer läuft wurde garantiert nicht so kompiliert, es sei denn du benutzt Gentoo. Die Stärke von Java ist ja gerade, dass es zur Laufzeit optimieren kann.

    Steffo: Kannst du mal die final aus dem Point raus machen und schauen, ob das was ändert?

    Kommt gleich. 😉

    L. G.
    Steffo



  • HereIGo schrieb:

    Steffo: Kannst du mal die final aus dem Point raus machen und schauen, ob das was ändert?

    Bei new Pi(10000):

    [steffo@localhost performance]$ time java Main
    3.14159053
    
    real	0m4.682s
    user	0m4.292s
    sys	0m0.523s
    

    Liebe Grüße
    Steffo



  • Steffo schrieb:

    ps: Bitte immer mit -march=native testen. Der Java-Jitter darf ja auch den Prozesssor kennen.

    Das mache ich extra nicht. Weshalb? Zeig mir mal Software, die auf diese Weise kompiliert wird. Das wird man in der Praxis kaum finden. Die Software, die auf deinem Computer läuft wurde garantiert nicht so kompiliert, es sei denn du benutzt Gentoo. Die Stärke von Java ist ja gerade, dass es zur Laufzeit optimieren kann.

    Ich kann doch auf der CD 12 verschiedene game.exe Dateien anbieten und vom Installer die passende auf die Platte rotzen. Nu werd mal nicht kindisch. Die exe ist so klein, davon kann man 100 draufrotzen, ohne zu leiden. Daß es unüblich ist, ist, weil es normalerweise nur 1% ausmacht. In so einem konstruierten Test solltest Du fair bleiben. Würde ein großer Unterschied sein, würde man 100 exe ausliefern. Da habe ich keine Bange. Da wir theoretisch damit rechnen müssen, daß -march=native viel bringt, um wissenschaftlich zu bleiben, mußt Du leider auch damit messen.



  • Wie auch immer, hat aber nichts gebracht. Das Ergebnis ist bei einem Radius von 10000 sogar schlechter als meine erste Messung. 🙂

    [steffo@localhost performance]$ g++ -O3 -march=native pi.cpp -o pi-cpp
    [steffo@localhost performance]$ time ./pi-cpp
    3.14159
    
    real	0m2.930s
    user	0m2.925s
    sys	0m0.004s
    

    Liebe Grüße
    Steffo



  • Steffo schrieb:

    Wie auch immer, hat aber nichts gebracht.

    Es hat gebracht, daß wir über den Zweifel erhaben sind, bewußt unfair gemessen zu haben. Das ist enorm viel, finde ich.



  • volkard schrieb:

    Steffo schrieb:

    Wie auch immer, hat aber nichts gebracht.

    Es hat gebracht, daß wir über den Zweifel erhaben sind, bewußt unfair gemessen zu haben. Das ist enorm viel, finde ich.

    Wie gesagt, ich sehe das anders. Dein Beispiel mit den verschiedenen Exe-Dateien mag bei x86 und x64 Architekturen in der Praxis stimmen, aber eine feinere Abstimmung wirst du nicht vorfinden, deshalb halte ich nicht all zu sehr von zu viel Theoretisierung - das ist ein beliebtes Mittel von Lobbyisten und Marketing-Leuten, aber nicht von Leuten, die mit beiden Beinen auf dem Boden bleiben.

    EDIT: Außerdem ist der Source frei verfügbar. Es steht jedem zu selbst zu messen, um sein eigenes Urteil zu bilden.

    L. G.
    Steffo



  • Einen Vorschlag zur Güte: Du testest immer beides, dann können wir nebenbei noch abschätzen wieviel die zusätzliche Optimierung bringen würde



  • Bei mir siehts aktuell interessanterweise so aus:

    $ time java Main

    real 0m0.253s
    user 0m0.283s
    sys 0m0.052s

    $ time ./prog
    3.14159

    real 0m0.605s
    user 0m0.513s
    sys 0m0.004s

    Beide mit 10k.



  • Hast du was am Code geändert?



  • Ich habe alles in eine Code-Datei gesteckt und die 2 public bei den Klassen weggemacht, ansonsten nichts. Allerdings sehe ich gerade, dass bei Java gar keine Ausgabe ist. Irgendwas ist da falsch.



  • Steffo schrieb:

    Wie gesagt, ich sehe das anders. Dein Beispiel mit den verschiedenen Exe-Dateien mag bei x86 und x64 Architekturen in der Praxis stimmen, aber eine feinere Abstimmung wirst du nicht vorfinden,

    WEIL im fertigen Game nur 1% rauskommt.

    Steffo schrieb:

    deshalb halte ich nicht all zu sehr von zu viel Theoretisierung

    Wir theoretisieren mit diesen künstlichen Test-Programmen. Da kann es schon vorkommen, daß memcpy ohne oder mit SSE gigantisch auseinanderliegen. WÜRDE man ein Programm verkaufen, das so künstlich ist wie unsere Testprogramme, und WÜRDE es einen deutlichen Unterschied machen, dann würde man auch 12 exe auf die DVD tun.

    Steffo schrieb:

    das ist ein beliebtes Mittel von Lobbyisten und Marketing-Leuten, aber nicht von Leuten, die mit beiden Beinen auf dem Boden bleiben.

    Mußt Du mich wirklich jetzt antrollen? Ich dachte, Du hättest Dich vorhin nur von PI reinziehen lassen. Das jetzt ist aber offensiv. Nee, mach das nicht. Wir haben wenig genug Leute, die nachdenken können UND oft nett bleiben. Dich hatte ich als Neuentdeckung im Auge, nachdem PI mich so enttäuscht hat.



  • @volkard: Ganz ruhig, ich wollte dich nicht antrollen. 🙂
    Deine Argumente kann ich nachvollziehen, danke.

    @Pi: Ich habe meine Tests in einer VM gemacht. Keine Ahnung, wie relevant das ist.

    L. G.
    Steffo



  • Seltsamerweise bekomme ich in der Eclipse eine Ausgabe. Ich habe es nun mit System.currentTimeMillis() gemacht, die Ausgabe sieht wie folgt aus:

    3.14159053
    1.001

    @volkard: Wodurch habe ich dich enttäuscht?

    Edit: Nachdem ich das Programm jetzt mehrmals gestartet habe, ging die Zeit von Java stark hinunter:

    3.14159053
    0.667

    Edit 2:
    Neuer Versuch, diesmal mit 100.000 (zugegebenermaßen habe ich keine Ahnung, wie sich das auf das Programm auswirkt, oder warum das Ergebnis falsch ist.)

    $ time ./prog
    -1.003

    real 0m49.951s
    user 0m49.841s
    sys 0m0.069s

    -1.0029964730543903
    64.401



  • 314159265358979 schrieb:

    Ich habe alles in eine Code-Datei gesteckt und die 2 public bei den Klassen weggemacht, ansonsten nichts. Allerdings sehe ich gerade, dass bei Java gar keine Ausgabe ist. Irgendwas ist da falsch.

    Habe ich auch mal ausprobiert, hat aber bei mir nichts gebracht.



  • 314159265358979 schrieb:

    zugegebenermaßen habe ich keine Ahnung, wie sich das auf das Programm auswirkt, oder warum das Ergebnis falsch ist.

    (105)2, was im Konstruktor von Pi berechnet wird, ist größer als 2^31.



  • Michael E. schrieb:

    314159265358979 schrieb:

    zugegebenermaßen habe ich keine Ahnung, wie sich das auf das Programm auswirkt, oder warum das Ergebnis falsch ist.

    (105)2, was im Konstruktor von Pi berechnet wird, ist größer als 2^31.

    Das muss jetzt aber für PI ziemlich erniedrigend sein. Schließlich hat er dich als dumm bezeichnet. 🙂



  • Steffo schrieb:

    Schließlich hat er dich als dumm bezeichnet. 🙂

    Habe ich nicht. Und wieder eine absichtliche Umformulierung. Und dann sagt mir volkard, ich soll nicht so aggressiv sein.



  • 314159265358979 schrieb:

    Steffo schrieb:

    Schließlich hat er dich als dumm bezeichnet. 🙂

    Habe ich nicht. Und wieder eine absichtliche Umformulierung. Und dann sagt mir volkard, ich soll nicht so aggressiv sein.

    OK, ich korrigiere mich, du hast ihn nur als "unglaublich blöd" und "ignoranten Trottel" bezeichnet.

    314159265358979 schrieb:

    Falsch, ich vergleiche noch gar nichts. Und wenn du nicht so unglaublich blöd wärst, hättest du dir denken können, dass das Resultat mit Java gleich kommt. Aber hauptsache gleich mal auf PI drauf, dabei hast du ja nichts zu befürchten, richtig? 🙄

    314159265358979 schrieb:

    Michael E. schrieb:

    314159265358979 schrieb:

    @Steffo: Nö, eine Minute schneller.

    ROFL 🤡 Weswegen hast du mich noch gleich beleidigt?

    Genau das meine ich. Ignoranter Trottel.

    Ich wollte dir nur zeigen wie unglaublich schnell solche Beleidigungen nach hinten gehen können und dass du das nächste mal besser überlegst bevor du irgendetwas auf die Tasten haust. - Das nur mal so als Tipp.

    L. G.
    Steffo


Anmelden zum Antworten