String-Prüfung: Was ist besser/schneller?

oldshoe

Bekanntes Mitglied
Hallo ich versuche gerade mein Programm zu optimieren. Ich habe einen String content und möchte mit diesen gewisse Operationen ausführen. Das ist natürlich nur sinnvoll wenn ein gewisser Inhalt vorhanden ist. Daher interessiert es mich bei den folgenden Fällen ein Performance-Unterschied besteht.

Java:
if (!("").equals(pageContent)){ do something}

Java:
if (pageContent.length()>1){ do something}
 
Zuletzt bearbeitet von einem Moderator:
warum etwas optimieren, was nichtmal einen bruchteil einer nanosekunde benötigt?
Ansonsten dürfte (intuitiv) das zweite etwas performanter sein, da im ersten statement ein neues String object erzeugt werden muss
 
Optimierung da der Content bis Megabyte-Größe ausfallen kann und diese Fallunterscheidung für viele "Contents" gemacht werden muss.

edit: oder besser:

Java:
if (!pageContent.isEmpty()){ do something}
??????:L
 
Zuletzt bearbeitet:
Ansonsten dürfte (intuitiv) das zweite etwas performanter sein, da im ersten statement ein neues String object erzeugt werden muss
Falsch, muss es nicht. Der leere String ist schon lange im Arbeitsspeicher, wenn nur die Klasse geladen ist. (Denke ich jedenfalls. 😀)

@oldshoe: Wenn du die 1.6 benutzt, kannst du [c]isEmpty()[/c] benutzen. Das ist nicht unbedingt schneller als [c]equals()[/c] oder [c]length()[/c], drückt es aber besser aus. [EDIT: zu langsam, warst schneller] Im Falle des leeren Strings hat [c]equals()[/c] sowieso konstante Laufzeit, weil garantiert die Länge zuerst abgeprüft wird (bzw. zumindest vor den einzelnen Zeichen).

Aber wenn ich raten darf: dein Performance-Problem kommt nicht von [c]equals()[/c] oder so, sondern wahrscheinlich daher, dass du überhaupt Strings verwendest. Es klingt für mich auf dem ersten Blick nach einem groben Designfehler. Wenn Geschwindigkeit also wirklich wichtig ist, solltest du mehr Code zeigen.

Ark
 
Zuletzt bearbeitet:
Falsch, muss es nicht. Der leere String ist schon lange im Arbeitsspeicher, wenn nur die Klasse geladen ist. (Denke ich jedenfalls. 😀)

Wann auch immer der leere String geladen werden muss, er verbaucht unnötig viel Speicher, da er eben unnötig ist um das zu prüfen, was geprüft werden soll.

Optimierung da der Content bis Megabyte-Größe ausfallen kann und diese Fallunterscheidung für viele "Contents" gemacht werden muss.

Sorry, aber ich behaupte, da optimierst du an der falschen stelle, da sich die unterschiede in einem so geringen Maße bewegen, dass du nichts davon spüren wirst.
 
Die zweite Frage die sich stellt: Muss es null safe sein?

"".equals --> false
foo.isEmpty() --> NPE

überlicherweise:
Java:
public static boolean isBlank(String s) { return s == null || s.length() == 0; }
// oder ab 1.6 auch
public static boolean isBlank(String s) { return s == null || s.isEmpty(); }
 
Wann auch immer der leere String geladen werden muss, er verbaucht unnötig viel Speicher, da er eben unnötig ist um das zu prüfen, was geprüft werden soll.
Es stimmt zwar, dass der leere String nicht benötigt wird, aber der Speicherverbrauch des leeren Strings bewegt sich in der gleichen Größenordnung wie der Speicherverbrauch eines Codes mit einem simplen if-else. Er könnte wahrscheinlich wesentlich mehr Speicher sparen, wenn er nur kürzere Bezeichner für Klassen und Fields benutzen würde. Kurzum: Es lohnt wirklich nicht. 😉

Ark
 
Bezeichner für variablen verbrauchen keinen Speicher, sie sind nur aliasnamen für entsprechende Speicheraddressen und werden im fertigen Programm (auf Maschinencode basis) nicht mehr auftauchen (meines wissenstandes nach)
 
Bezeichner für variablen verbrauchen keinen Speicher, sie sind nur aliasnamen für entsprechende Speicheraddressen und werden im fertigen Programm (auf Maschinencode basis) nicht mehr auftauchen (meines wissenstandes nach)
Und wie funktioniert dann Reflection? Für Variablen auf dem Stack könnte das stimmen, aber ich denke doch, dass zumindest Klassen und Felder mit ihrem vollen Namen gespeichert werden.

Ark
 
Bezeichner für variablen verbrauchen keinen Speicher, sie sind nur aliasnamen für entsprechende Speicheraddressen und werden im fertigen Programm (auf Maschinencode basis) nicht mehr auftauchen (meines wissenstandes nach)
Hier werden ein paar Dinge durcheinander gewürfelt ...
Was hat Java mit Maschinencode zu tun? 😉
Mit Optimierungen hat das alles nix zu tun.

Abgesehen davon kann man davon ausgehen das es bei Java zur Laufzeit immer einen String "" gibt, und String Literale werden durch den Compiler und die VM optimiert.

Annahmen über Laufzeitverhalten durch Quelltextlesen ist kein gutes Mittel für Optimierungen, Profiler sind es.
 
Reflection ist ja auch ein Performance Killer und sollte deswegen solchen anwendungen vermieden werden.
Einer der Gründe liegt genau darin, dass der Compiler sich dann die Bezeichner zwischenspeichern muss.

Oracle hat gesagt.:
Performance Overhead
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

Quelle: Trail: The Reflection API (The Java™ Tutorials)

Was hat Java mit Maschinencode zu tun? 😉
Auch java wird in Maschinencode umgewandelt, wenngleich diese Aufgabe gott sei dank auch von der JVM durchgeführt wird.
 
Zuletzt bearbeitet:
@Sonecc: Guck dir mal eine class-Datei in einem Hex-Editor an, vor allem den Anfang. Und drücke dich bitte klarer dahingehend aus, welchen Compiler (Bytecodecompiler, HotSpot-Compiler etc.) du gerade meinst. Das würde einige Missverständnisse vermeiden. 😉

Ark
 
Auch java wird in Maschinencode umgewandelt, wenngleich diese Aufgabe gott sei dank auch von der JVM durchgeführt wird.
Wie gesagt, du verwechselst da ein paar Sachen...

Dein Argument, dass Variablennamen angeblich keinen Speicher beanspruchen ist falsch, stehen alle noch im Bytecode, und der Bytcode ist dein "fertiges Programm", nicht der Machinencode der erst viel später zur Laufzeit erzeugt wird.
 

Zurück
Oben