ich soll einen plattformunabhängigen Funktionskern für eine Anwendung schreiben.
Geplant ist: Funktionskern in C++ um diese Funktionen überall nutzen zu können und weil es schneller ist wie Java.
Allerdings müsste ich für jedes System eine extra Oberfläche basteln denke ich, was mir bei Java erspart bliebe.
Die Frage ist jetzt: Mit welcher Programmiersprache?
Es geht darum das Dateien verglichen und verschoben werden sollen.
Das Argument was gegen Java spricht ist, das Java "verdammt lahm ist" laut meinem Chef.
Stimmt das? Oder hat sich da in den letzten Jahren/Versionen so viel getan das Java mit der Geschwindigkeit mithalten kann?
Nein, so stimmt es nicht. Es gibt Bereiche in denen Java weiterhin langsamer als native Kompilate arbeitet, dafür ist es in anderen Bereichen schneller.
Je nachdem was du vorhast mit den Dateien zu machen ist übrigens nicht die Programmiersprache entscheidend.
das Paket java.nio verwendet die Techniken des zugrundliegenden Betriebsystems für Dateioperationen, kommt für die meisten Anwendungsfälle also auf vergleichbare Geschwindigkeiten wie beispielsweise ein C Kompilat. Ich sage hier für die meisten Anwendungsfälle, da massives bitschubsen auf primitiver Ebene bei Java vermutlich einen gewissen Overhead mitbringt.
Für die GUI kann man in jedem Fall Java verwenden, allerdings ist es auch nur bedingt spaßig eine Java GUI für ein C Programm zu schreiben.
Wenn du mehr Details nennst, kann man vielleicht eine genauere Aussage treffen.
Im Prinzip geht es darum über Netzwerk, Client/Server-mäßig viele tausende kleine und große Dateien inhaltlich zu vergleichen und auszutauschen, also zu kopieren.
Wenn Java das genauso schnell kann wie andere Sprachen müsste man nix abkapseln.
Was mich jetzt irritiert: Jeder Programmierer in den veschiedensten Foren sagt mir, das Java genauso schnell ist.
Hier in der Firma sagt jeder das Java langsamer ist. Warum ist Java denn jetzt genausoschnell? Es wird doch interpretiert, braucht doch dann auch allein dafür schon ewig, oder nicht?
Wenn Du das Ausführen von Maschinencode auf einem Intelprozessor als interpretieren bezeichnest, dann ist das Ausführen von Bytecode in einer Virtualmachine ebenso interpretieren.....
aber die virtualmachine muss doch aus dem Bytecode einen Maschinencode erzeugen und diesen an den prozessor weiterleiten.. das ist für mich "interpretieren"
Davon abgesehen das Java (wie oben erwähnt) nicht interpretiert wird:
Der Grund warum Java sehr viel schneller als zu dessen Anfangszeiten ist, lässt sich maßgeblich auf zwei Entwicklungen zurückführen:
Den Hotspot und den JIT Compiler. Der Hotspot Compiler kann performancekritischen Code zur Laufzeit optimieren, der JIT Compiler übersetzt bei Bedarf zur Laufzeit in natives Kompilat.
Beide sind natürlich gleichzeit aktiv und fester Bestandteil der JRE.
Da alles zur Laufzeit passiert, kann deutlich besser optimiert werden als bei Sprachen wie C.
Der Nachteil hingegen ist, dass die Optimierung erst nach einer bestimmten Zeitspanne umgesetzt wird (nach der fest steht welche Teile des Codes kritisch sind). Für sehr kurzlebige Programme (zB wenige Sekunden) eignet sich diese Optimierung daher nicht.
Ein Java Programm wird allerdings immer langsamer sein als ein (für die exakte passende Laufzeitumgebung) hochoptimiertes ASM Programm. In der Praxis ist diese Optimierung normalerweise jedoch nicht durchführbar (alleine schon weil man nicht für jedes einzelne Kundensystem kompilieren will :wink.
Java bietet daher einen sehr guten Kompromiss aus Ausführungsgeschwindigkeit und Entwicklungszeit.
Wenn Performance jedoch das absolute Hauptziel der Entwicklung ist und jede Millisekunde zählt, dann doch eher C oder direkt ASM.
Für normale Desktop und Server Anwendungen ist Java allerdings (aus genannten Gründen) die verbreitetste Sprache.
Man muss eben seine Erfahrungen machen und diese nutzen um zu entscheiden, ob im konkreten Fall die Entwicklungszeit oder die Laufzeit kritischer zu bewerten ist. Beides hängt natürlich auch nicht unwesentlich (oder in vielen Fällen hauptsächlich) vom Können des Entwicklerteams ab.
Wie gut ist das Design der Anwendung? Wie gut sind Datenstrukturen und Algorithmen in Hinsicht auf die Anforderungen an Speicherverbrauch und Laufzeit gewählt? Wie gut beherrschen die Umsetzenden Sprache, Entwicklungsumgebung und Tools? ....
Ich würde mutmaßen, dass diese "weichen" Faktoren in den meisten Fällen wesentlich schwerwiegender sind, als die Ergebnisse irgendwelcher künstlicher Mikrobenchmarks von Sprache A gegen Sprache B.
Ich würde mutmaßen, dass diese "weichen" Faktoren in den meisten Fällen wesentlich schwerwiegender sind, als die Ergebnisse irgendwelcher künstlicher Mikrobenchmarks von Sprache A gegen Sprache B.
Erstens kann ich dem nur zustimmen, und zweitens sind Mikrobenchmarks sehr oft schlecht implementiert, wenig aussagekräftig und irreführend.
Das Laufzeitverhalten einzelner Anwendungskomponenten (oder der Anwendung insgesamt) unter Last und über einen längeren Zeitpunkt ist meiner Meinung nach meistens der relevantere Wert.
Wie die WildeKarte schon sagte (das reimt sich^^) :
Dateioperationen mit java.nio werden auf betriebsystemebene durchgeführt. Der name Nativ Input Output sollte diese Ausage stärken.
Der Hotspot und JIT in Java 6 ist einfach nur klasse. Die Startzeit meiner Programme haben sich vom umstieg auf JSE6 deutlich verkürzt. Das war/ist nämlich eines der einizigen Preformance krisitschen situationen die ich bischer kenne.
Erst vor kurzem hab ich mein 'Installshied' fertiggestellt, indem auch Daten kopiert werden. Allerdings auf basis von java.io, also nicht java.nio.
Aus neugier hab ich die selben Daten mit Copy&Paste kopiert. Also direkt im windows explorer.
Ich hab zwar nicht Programmtechnisch gebencht, aber mithilfe von 'auf die Uhr gucken' konnte ich keinen nennenwerten unterschied feststellen. Immerhin wurden ca. 50Mb kopiert.
Aus weiterer neugier hab ich einen Preisberechnungsprogramm in Delphi umgeschrieben. OK, ich muss sagen der erste start des Java Programms war deutschlich langsamer, warscheinlich weil die JVM bis dato nicht geladen wurde. Beim zweiten start des Rechners hat sich die Startzeit zwar deutlich verkürzt, war aber immer noch mekrlich langsamer als die Delphi exe.
Ist das Programm erstmal gestartet, wird man als Mensch kaum noch einen unterschied feststellen können.
Im Prinzip geht es darum über Netzwerk, Client/Server-mäßig viele tausende kleine und große Dateien inhaltlich zu vergleichen und auszutauschen, also zu kopieren.
Wenn Java das genauso schnell kann wie andere Sprachen müsste man nix abkapseln.
Bei dieser Anwendung wartest du sowieso häufig auf das Netzwerk und/oder die Platte. Es ist daher völlig Wumpe, ob Java das letzte bisschen Performance beim Vergleich liefern kann oder nicht. Im Gegenzug bekommst du ein einfach zu verwendendes Threadhandling an die Hand, was evtl. für Optimierungen gerade in IO-limitierten Situationen wie dieser nützlich sein kann.
Geplant ist: Funktionskern in C++ um diese Funktionen überall nutzen zu können und weil es schneller ist wie Java.
Allerdings müsste ich für jedes System eine extra Oberfläche basteln denke ich, was mir bei Java erspart bliebe.
viele vergessen in diesem Zusammenhang das gute alte Gespann TCL/TK, um plattformunabhängig Oberflächen für zugrunde liegende C++ Kolosse zu schreiben.
Nachteil ist hierbei, dass der Kunde sich ein TCL/TK Paket installieren muss.
OK, weitere Funktion: eine Anwendung soll als Dienst/Daemon laufen, gibts da etws was für/gegen Java/C++ spricht?
Java Anwendungen als Dienst laufen zu lassen geht ja mit diesem ServiceWrapper, also gehen sollte das. wie sieht es da bei C++ aus?
Wie sieht es mit der GUI bei nem Dienst aus? Die haben keine oder?
Kann man eigentlich auch eine Java-Anwendung in eine exe Datei compilieren? Also so das nixmehr in der JVM ausgeführt wird, sondern direkt für ein System compiliert wird?
ja aber wenn ich den Code für jedes System ausführbar compiliere, bei Windows eben als exe, dann dürfte es keine Geschwindigkeitsverluste mehr gegenüber C++ geben oder?
ja aber wenn ich den Code für jedes System ausführbar compiliere, bei Windows eben als exe, dann dürfte es keine Geschwindigkeitsverluste mehr gegenüber C++ geben oder?
du wirst immer die VM haben muessen ! wenn du es als exe kompilierst musst du die VM miteinpacken... ganz ohnen geht nicht (waere ja auch absolut unlogisch).
das ausfuehrbare system bei java ist die jar - und der ist es egal auf welchem System dies geschieht und jedes System kann die jar ausfuehren
ja aber wenn ich den Code für jedes System ausführbar compiliere, bei Windows eben als exe, dann dürfte es keine Geschwindigkeitsverluste mehr gegenüber C++ geben oder?
Mit GCJ sollte das funktionieren. Allerdings muss man soweit ich weiß auf aufwändige GUI's verzichten. Auf Swing muss man glaub ich ganz verzichten, bin aber auch nicht sicher.
Ich hatte auch schon eine Demo eines; ich will es mal 'umwandler' nennen. Dieser hat fertigen Bytecode in Nativen Code übersetzt, bzw eine exe daraus erstellt. Das ganze hat mit einem Consolen-Programm auch wunderbar funktioniert, wie es mit GUI's aussieht - keine ahnung.
Und was macht die VM mit dem Bytecode zur Laufzeit? Interpretieren... nicht wahr? Oder wie wird der Java-Bytecode in Maschinencode umgewandelt?
Ohne HotSpot-Technologie würde der Java-Bytecode sogar jedesmal auf neue interpretiert werden, deswegen waren die ersten Java-Versionen (bzw deren VMs) auch so langsam. Inzwischen wird aber standardmäßig die HotSpot-Technologie verwendet, d.h. häufig benutzte Codeteile bleiben kompiliert im Speicher (wobei noch Optimierungen vorgenommen werden können, weil komplette Codeblöcke kompiliert werden), Variablen werden über Pointer direkt adressiert usw.
Da kann aber auch jemand wieder argumentieren, dass die VM eben den Bytecode interpretiert, um ihn auszuführen. Es ist wie gesagt eine Definitionssache.
Higher-level programming languages are generally divided for convenience into compiled languages and interpreted languages. However, there is rarely anything about a language that requires it to be exclusively compiled, or exclusively interpreted. The categorization usually reflects the most popular or widespread implementations of a language — for instance, BASIC is thought of as an interpreted language, and C a compiled one, despite the existence of BASIC compilers and C interpreters.
In a sense, all languages are interpreted, with "execution" being merely a special case of interpretation performed by transistors switching on a CPU. Modern trends toward just-in-time compilation and bytecode interpretation also blur the traditional categorizations.
Man könnte auch argumentieren, dass die CPU die High-Level CISC Mnemonics in Low-Level ROPs aufsplittet und darum die ganze Intel(-kompatible)-Welt eh mittlerweile auf Interpretern basiert....
Man könnte auch argumentieren, dass die CPU die High-Level CISC Mnemonics in Low-Level ROPs aufsplittet und darum die ganze Intel(-kompatible)-Welt eh mittlerweile auf Interpretern basiert....
Irgendwie ist das ja auch richtig. Wäre es nicht sinnvoller, diese Abwärtskompatibilität langsam mal aufzugeben? Würde doch sicher mehr Performance bringen, oder? ???:L
Wenn man Linux darauf portieren würde, müsste doch eigentlich eine Menge Software laufen, wenn sie nur neu kompiliert wird, oder?
Aber meine Frage war eigentlich mehr, ob dadurch ein großer Performance-Verlust entsteht oder nicht.
Das ist die alte Frage "RISC vs. CISC", die heutzutage dadurch beantwortet wird, dass sie nicht beantwortet wird. Die CISCs sind lange schon nicht mehr nur CISC (man kann sie auch als CISC-Interpreter mit RISC-Kern betrachten), die RISCs eigentlich auch keine RISCs (zig hundert Befehle; alles andere als einfache Designs)....
Ich würde sagen der letzte echte Mainstream-RISC war DECs Alpha (Oder sind es die ARMs?), während Intel mit dem P4 ordentlich durcheinander gewürfelt hat.
Performancegewinn oder -verlust ist eine Frage dessen, womit man vergleicht. Da man nur existierende System halbwegs vergleichen kann, dürfte man sich schwer tun. Am Ende setzt sich durch, was brauchbar und bezahlbar ist. Ein Blick auf die Supercompiting Top 500 verrrät, dass die Intels und AMDs dort längst eine beherrschende Stellung haben. Power, Cell, SPARC oder gar NEC Vektorprozessoren haben ihre Nischen, mehr auch nicht.
Klar abgrenzbare Ansätze in den Architekturen, die dann konsequent in einem Design umgesetzt wurden, gabs vor und nach Cell im Grunde nicht und die haben auch noch nicht viel auf die Beine gestellt.
Selbstverständlich wird der Bytecode von Java von der VM interpretiert ist ähnlich wie eine .exe von VisualBasic oder wie bei C# mit dem .NET Framework.
hier auch mal ein Auszug von Wikipedia
Java-Programme werden in Bytecode übersetzt und dann in einer speziellen Umgebung ausgeführt, die als Java-Laufzeitumgebung oder Java-Plattform bezeichnet wird. Deren wichtigster Bestandteil ist die Java Virtual Machine (Java-VM), die die Programme ausführt, indem sie den Bytecode interpretiert.
Ich verstehe nicht warum das nicht zugegeben wird, für eine Sprache die interpretiert ist sie doch sauschnell sogar so schnell das ein Renderer wie Sunflow damit geschrieben wird der wirklich realistische Bilder berechnet.
Ich verstehe nicht warum das nicht zugegeben wird, für eine Sprache die interpretiert ist sie doch sauschnell sogar so schnell das ein Renderer wie Sunflow damit geschrieben wird der wirklich realistische Bilder berechnet.
Die Sprache ist Java und Java wird nicht interpretiert.
Interpretiert wird der Bytecode, und daduch gibt es auch viel Raum für Optimierugnen durch die Hotspot VM.
Zum Beispiel: Was ist schneller, Zeichenverkettungen mit Strings, StringBuffer oder StringBuilder?
Antwort: Strings! Und besser lesen lässt es sich auch noch
hast recht, in deinem Beispiel, ist der StringBuilder unschlagbar schnell.
Wie du ja weisst liegt das hauptsächlich daran, dass in ersterem Beipsiel jedesmal ein neues String Objekt erzeugt wird, in letzterem wird einfach der schon vorhandene StringBuilder verwendet.
Allerdings ist das nicht in Stein gemeiselt Mircobenchmarks haben so ihre Tücken...
Nehmen wir mal an, dass das verketten von Strings in einer Methode passiert, die wirklich sehr oft aufgerufen wird, und diese Methode gibt immer einen String zurück, d.h. es muss immer ein neues Objekt erstellt werden, zumindest aus Sicht des Programmierers:
Code:
final static String concatWithStrings( final String str1, final String str2 ) {
return str1 + str2;
}
Im Vergleich dazu dasselbe mit einem StringBuilder:
Code:
final static String concatWithStringBuilder( final String str1, final String str2 ) {
StringBuilder result= new StringBuilder();
result.append( str1 ).append( str2 );
return result.toString();
}
Hier ist das ganze dann anders
Hier ein kleines Beispielprogramm:
Code:
package foo;
public class PerfTest {
public static void main(String[] args) throws Exception {
String str = "";
int durchgänge= 100000;
long startTime= System.nanoTime();
long timeElapsed;
System.out.println( "For-Schleife mit String: " );
for(int i = 0; i < durchgänge; i++)
str += "x";
timeElapsed= System.nanoTime() - startTime;
System.out.println( timeElapsed );
str = "";
System.out.println( "For-Schleife mit StringBuilder: " );
startTime= System.nanoTime();
StringBuilder strB = new StringBuilder();
for(int i = 0; i < durchgänge; i++)
strB = strB.append("x");
timeElapsed= System.nanoTime() - startTime;
System.out.println( timeElapsed );
str= "";
System.out.println( "For-Schleife mit Funktionsaufruf und String: " );
startTime= System.nanoTime();
for(int i = 0; i < durchgänge; i++)
str= concatWithStrings( str, "x" );
timeElapsed= System.nanoTime() - startTime;
System.out.println( timeElapsed );
startTime= System.nanoTime();
System.out.println( "For-Schleife mit Funtkionsaufruf und StringBuilder: " );
for(int i = 0; i < durchgänge; i++)
str = concatWithStringBuilder( str, "x" );
timeElapsed= System.nanoTime() - startTime;
System.out.println( timeElapsed );
}
final static String concatWithStrings( final String str1, final String str2 ) {
return str1 + str2;
}
final static String concatWithStringBuilder( final String str1, final String str2 ) {
StringBuilder result= new StringBuilder();
result.append( str1 ).append( str2 );
return result.toString();
}
}
Starte ich das und will das die Client VM benutzt wird, läuft es so:
java -client foo.PerfTest
For-Schleife mit String:
20744478697
For-Schleife mit StringBuilder:
3734762
For-Schleife mit Funktionsaufruf und String:
20736109407
For-Schleife mit Funtkionsaufruf und StringBuilder:
300872102320
Im Gegensatz dazu dasselbe nochmal mi der Server VM:
java -server foo.PerfTest
For-Schleife mit String:
17666163926
For-Schleife mit StringBuilder:
7359525
For-Schleife mit Funktionsaufruf und String:
17743117701
For-Schleife mit Funtkionsaufruf und StringBuilder:
100023550340
Tja, plötzlich sind Strings viel schneller, zumindest wenn die Verkettung in der Methode passiert und dabei ein neuer StringBuilder und String (result.toString) erzeugt werden muss.
Ich finde, man sollte immer so schreiben, das man es einfacher lesen kann.
Falls mein Programm dann zu langsam läuft, brauch ich einen Profiler um herauszufinden, was genau zu langsam ist, man erinnere sich an die 80-20 Regel (oder besser 95-5 Regel), die meisten Ressourcen verbraucht nur ein Bruchteil eines Programmes.
Nebenbei gefragt, wer kennt einen guten (und am besten freien) Java-Profiler?
Die Sprache ist Java und Java wird nicht interpretiert.
Interpretiert wird der Bytecode, und daduch gibt es auch viel Raum für Optimierugnen durch die Hotspot VM.
Ähm, ist das nicht so das der Bytecode zu 100% dem Javacode entspricht?
Mit Programme wie DJ Java Decompiler kann doch auch aus dem Bytecode zu 100% der Javacode erzeugt werden, nur halt ohne Kommentare und Variabelnnamen, deswegen sind ja Javaprogramme auch immer Opensource.
OpenSource sind mal nicht! Weil das ist Diebstahl wenn du das dekompilierst und benutzt!
Man kann C++ Programme auch disassemblen (und sogar in C wieder zurückwandeln, nur nicht einwandfrei - aber deswegen ist das nicht OpenSource).
Desweiteren entspricht er nicht 100% dem JavaCode, da der Compiler schon beim Kompilieren ein paar "Optimierungen" vornimmt und du so nicht immer 1:1 den gleichen Code rauskriegst!
Ähm, ist das nicht so das der Bytecode zu 100% dem Javacode entspricht?
Mit Programme wie DJ Java Decompiler kann doch auch aus dem Bytecode zu 100% der Javacode erzeugt werden, nur halt ohne Kommentare und Variabelnnamen, deswegen sind ja Javaprogramme auch immer Opensource.
Trotzdem programmiert man nicht in Byte Code
Ausserdem sind Java Programme nicht immer Open Source... und die Variblennamen bleiben erhalten, wenn man denn möchte.
Man kann auch Code-Obfuscator einsetzen, und zu verschleiern was ein Programm macht, da ist nix mit 100%, nichtmal mit 50%...
Mal abgesehen davon, der Unterschied zwischen einer Interpretierten Sprache und einer Kompilierten Sprache ist nur, wie die Sprache in ausführbaren Code übersetzt wird, sonst nix.
Zur Klarstellung: Kompilierte Sprachen werden in einem Rutsch übersetzt, bei Interpretierten Sprachen geschieht das Zeilenweise während der Ausführung.
Klarstellung: the Java bytecode is interpreted or converted to native machine code by the JIT compiler.
Also isses interpretiert, da nicht alles in einen maschinencode umgewandelt wird ^^
Ums einfacher zu machen: der bytecode kann ja so nicht ausgeführt werden! Es dient lediglich dazu, das jeder den gleichen Code hat (egal welches OS). Die JVM (das einzige Teil das streng genommen Plattformunabhängig ist, bzw eben die API für die Java Programme bildet) interpretiert dann den byteCode und wandelt den ggf in Maschinencode um, bzw ruft gleich library Methoden( die in den .dll oder .so Dateien sind) auf und befühlt die API Anfragen.
Die VM in denen Java läuft, ist für das Java Programm ja immer das gleiche! Daher ist die JVM ja überall gleich und von keinem OS Abhängig! Dadurch entsteht diese "Plattformunabhägingkeit" obwohl halt alles von der JVM abhängt! Gibts keine JVM für die Plattform, geht auch keine Java.
Und da die JVM für jedes OS kompiliert werden muss, isses streng gesehen auch keine Plattformunabhängige Sprache :bae:
Einfach in jedem OS ein mini OS (die JVM) vorgaukeln welches eine API Schnittstelle zu dem OS bildet und dann sagen das ist Plattformunabhängig ist halt so ne Sache
Aber da könnte man wahrscheinlich ewig drüber diskutieren...
Wichtig ist dich, ob die Sprache kompiliert wird und so der Kompiler in der Lage ist, Syntax- und Semantikfehler anzuzeigen und das kompilieren zu verhindern falls welche vorhanden sind.
Ein Beispiel für eine interpretierte Sprache wäre JavaScript (wie fast alle Scriptsprachen), der JS Interpreter hört auf das Script auszuführen, sobald er einen Syntaxfehler entdeckt... ich denke jeder hat schon mal darüber geflucht, dass soclhe Fehler erst beim ausführen entdeckt werden.
In Java passiert so etwas nicht, da der gesamte Quelltext zuerst kompiliert wird, und dass auch nur wenn keine Syntaxfehler vorhanden sind.
Auf den Bytecode kommt es aber beim Starten der Anwendung an und der wird interpretiert, also für mich ist das glasklar dass JAVA, C#/.NET etc interpretierende Sprachen sind, die ganz leicht durch eine Kompilierung optimiert werden.
Man muss aber erwähnen, das die Geschwindigkeit von heutigen Interpreter-Sprachen im Vergleich zu dem früheren QBasic durch neue Technologien stark gestiegen ist. Nichts zum troz hat JAVA mehr mit Basic gemeinsam als mit z.B C++ was die Ausführung und nicht den Sytrax oder OOP angeht.
Kompilierte Sprachen sind für mich immer die, die so wie sie kompiliert worden sind auch ausgeführt werden und das wird Java und C#/.NET definitiv nicht, sonst wäre ja auch das ganze Konzept mit dem JIT oder CLR was die Sprachen so gut macht dahin.
Java wird nicht interpretiert, der Bytecode wird interpretiert. Der Unterschied wird deutlicher, wenn man sich vor Augen hält, das nicht nur Java Bytecode auf einer JVM läuft.