Java vs. C. Performance-Vergleich
-
Der JIT hat da gerade mal an der Oberfläche gkratzt da wird in der Richtung noch einiges passieren. Von der Theorie her könnte ein JIT jedes statische Kompiliat, solange es nicht nur auf eine CPU hin hochoptimiert wurde, schlagen. Da er das umliegende System zur Laufzeit erfassen kann und alles nutzen kann was die CPUs hergeben.
Wenn viel Speicher ins Spiel kommt ist ein gescheiter GC eh besser gegen Fragmentierung.
-
schnellschneller schrieb:
Von der Theorie her könnte ein JIT jedes statische Kompiliat, solange es nicht nur auf eine CPU hin hochoptimiert wurde, schlagen. Da er das umliegende System zur Laufzeit erfassen kann und alles nutzen kann was die CPUs hergeben.
In theory, there is no difference between theory and practice. But, in practice, there is.
schnellschneller schrieb:
Wenn viel Speicher ins Spiel kommt ist ein gescheiter GC eh besser gegen Fragmentierung.
kommt darauf an in welcher blockgröße du dir das vom os besorgst. imho wird die arbeit mehrfach gemacht. einmal vom os und dann von der clib/java mit dem unterschied dass ich auf das java teil nicht verzichten kann weil es bestandteil der sprache ist.
-
Ein viertel der Geschwindigkeit bei einer sehr rechenintensiven Anwendung ist schon einmal nicht schlecht wenn man bedenkt dass dadurch der ganze hässliche C++ mit all seinen Altlasten und Unannehmlichkeiten weg fällt und man sauberen und schön wartbaren Code erhält. Java wird ja auch nicht langsamer in Zukunft werden, sondern eher noch mehr aufholen.
-
nichtschlechtherrspecht schrieb:
Ein viertel der Geschwindigkeit bei einer sehr rechenintensiven Anwendung ist schon einmal nicht schlecht wenn man bedenkt dass dadurch der ganze hässliche C++ mit all seinen Altlasten und Unannehmlichkeiten weg fällt und man sauberen und schön wartbaren Code erhält. Java wird ja auch nicht langsamer in Zukunft werden, sondern eher noch mehr aufholen.
Java ist vermutlich grade dabei, Altlasten aufzubauen^^
-
So lange da nicht mit Header- und Implementierungsdateien und mit Makros für die verschiedenen Compiler und Plattformen gewurstelt werden muss geht das noch in Ordnung.
-
najasolala schrieb:
So lange da nicht mit Header- und Implementierungsdateien und mit Makros für die verschiedenen Compiler und Plattformen gewurstelt werden muss geht das noch in Ordnung.
und denkst in java wird gezaubert? die c performance kommt größtenteils daher, dass viele std. lib implementationen in assembler programmiert sind. das ist nicht notwendig bingt aber geschwindigkeit. aber ihr in java versteckt euch lieber hinter ner 50mb runtime nach dem motto was ich nicht weiß macht mich nicht heiß...
@edit: und das schlimme, ihr denkt dann noch es würde nicht existieren.
-
SunflowRay schrieb:
Der Raytracer Sunflow ist in der Javaversion gerade mal 20% langsamer also macht es auch bei rechenintensiven Aufgaben nicht immer einen großen Unterschied ob nun C/C++ oder Java.
http://strattonbrazil.blogspot.com/2008/11/sunflow-java-ray-tracer.html
20 % ist kein großer Unterschied??????
-
dloooooooooooooool schrieb:
SunflowRay schrieb:
Der Raytracer Sunflow ist in der Javaversion gerade mal 20% langsamer also macht es auch bei rechenintensiven Aufgaben nicht immer einen großen Unterschied ob nun C/C++ oder Java.
http://strattonbrazil.blogspot.com/2008/11/sunflow-java-ray-tracer.html
20 % ist kein großer Unterschied??????
Nö eigentlich nicht, aber in deinem Alter ist ja auch noch jeder Geburtstag was besonderes...
Was mich wundert, ist warum hier jemand nach fast einem Jahr noch antwortet und warum der Thread überhaupt noch offen ist
-
nöööööö denn 20% Unterschied haste heute schon bei unterschiedlichen CPU caches aus der gleichen Prozessorfamilie. Wenn man hochoptimiert mit C++ arbeitet müsste jedes Programm für jede unterschiedlich CPU neu kompiliert werden um wirklich den großen Unterschied zu bewirken, meist sind sie aber gerade mal für 386 oder 686 kompiliert und sowas könnte ein JIT in Zukunft auf jeden Fall schlagen und das ohne 100 C++ Tricks und Regeln anwenden zu müssen.
-
Den schnellsten Algorithmus wählt der Programmierer die beste Anpassung auf die jeweilige Umgebung der JIT, denn das kann bei zunehmender Komplexität kein Programmierer mehr für alles Umgebungen wirtschaftlich hin bekommen.
-
Den schnellsten Algorithmus wählt der Programmierer die beste Anpassung auf die jeweilige Umgebung der COMPILER
-
Trollalarm
-
donkong schrieb:
Den schnellsten Algorithmus wählt der Programmierer die beste Anpassung auf die jeweilige Umgebung der COMPILER
Weil auch für jede Umgebung neu kompiliert, gelle?
-
nichtschlechtherrspecht schrieb:
Ein viertel der Geschwindigkeit bei einer sehr rechenintensiven Anwendung ist schon einmal nicht schlecht wenn man bedenkt dass dadurch der ganze hässliche C++ mit all seinen Altlasten und Unannehmlichkeiten weg fällt und man sauberen und schön wartbaren Code erhält.
Ein Viertel ist absolut unterirdisch und für HPC total ungeeignet.
-
Ich finde es immer wieder erstaunlich, dass man mit demselben Thema immer wieder denselben Flame auslöst!
-
Das haben wir mal an unserer FH programmiert:
/* bubblesort.c */ #include <stdlib.h> #include <stdio.h> #include <time.h> int main(int argc, char *argv[]) { int *a; int i = 0; int j = 0; int tmp = 0; const int arraysize = atoi(argv[1]); srand(time(NULL)); a = (int *) malloc(arraysize * sizeof(int)); if (!a) return 1; for (i = 0; i < arraysize; ++i) { a[i] = rand(); } /* Zahlen sortieren */ for (i = arraysize; i > 1; i--) { /* groessten Wert nach hinten schieben */ for (j = 0; j < i - 1; ++j) { if (a[j] > a[j + 1]) { /* Werte tauschen */ tmp = a[j + 1]; a[j + 1] = a[j]; a[j] = tmp; } } } free(a); return 0; }
// Bubblesort.java import java.util.Scanner; import java.util.Random; public final class Bubblesort { private Bubblesort() { } /** * main ist der Startpunkt des Programms. * @param args wird nicht verwendet. */ public static void main(final String[] args) { final Scanner stdin = new Scanner(System.in); final Random random = new Random(); //----------------------------------------------- Feldgroesse einlesen final int n = Integer.parseInt(args[0]); //---------------------------------------------------- Zahlen einlesen final int[] a = new int[n]; for (int i = 0; i < a.length; ++i) { a[i] = random.nextInt(); } //--------------------------------------------------- Zahlen sortieren for (int i = a.length; i > 1; i--) { // groessten Wert nach hinten schieben for (int j = 0; j < i - 1; ++j) { if (a[j] > a[j + 1]) { // Werte tauschen int tmp = a[j + 1]; a[j + 1] = a[j]; a[j] = tmp; } } } } }
Gemessen wurde mit dem Unix-Tool "time". Das bedeutet soweit ich weiss, dass auch die VM-Ausführungszeit von Java gemessen wird.
Folgendes kam raus:[steffo@localhost aufgabe2]$ time java Bubblesort 10000 real 0m1.554s user 0m1.100s sys 0m0.494s [steffo@localhost aufgabe2]$ time ./bubblesort 10000 real 0m1.653s user 0m1.631s sys 0m0.018s
Relevant ist hier nur die User-Zeit, wo Java gut eine halbe Sekunde schneller ist.
Wenn jedoch mit GCC -O kompiliert wird, sieht es wieder ganz anders aus:
[steffo@localhost aufgabe2]$ time ./bubblesort 10000 real 0m0.667s user 0m0.660s sys 0m0.004s
Hier ist C knapp 1 Sekunde schneller als Java.
Liebe Grüße
Steffo
-
Niemanden interessiert es, wie schnell oder langsam unoptimierter Code ist. Erst Recht nicht nach einem Jahr. Mach aus -O mal -O3 -march=native und staune. Du könntest sogar eine Laufzeit von ca. 0 bekommen.
-
@Steffo: Sortier mal ein größeres Array, damit Du nicht nur den Startup der VM misst. Mach es einfach 10 mal so groß. Und dann gib am Ende irgendetwas aus dem Array aus, damit das nicht alles wegoptimiert wird.
-
Gregor schrieb:
@Steffo: Sortier mal ein größeres Array, damit Du nicht nur den Startup der VM misst. Mach es einfach 10 mal so groß. Und dann gib am Ende irgendetwas aus dem Array aus, damit das nicht alles wegoptimiert wird.
[steffo@localhost aufgabe2]$ time ./bubblesort 100000 a[0]=670 real 1m17.174s user 1m17.112s sys 0m0.026s [steffo@localhost aufgabe2]$ time java Bubblesort 100000 a[0]=-2147458265 real 1m47.629s user 1m47.539s sys 0m0.875s
Eine Laufzeit von 0 ist das natürlich nicht, aber C bleibt ungeschlagen.
Liebe Grüße
Steffo
-
Und was lernen wir daraus?
1. Mit dem richtigen Algorithmus (z.B. Mergesort) kann man viel mehr raus holen, als mit der Programmiersprache.
2. C++ ist die Englische Küche unter den Programmiersprachen.