Datentypen Welche Methode hat die bessere Performance?

goldmensch

Mitglied
Hey, ich hatte mich letzte Zeit bisschen mit der Performance Optimierung von Java beschäftigt. Und hab eine Methode bisschen abgewandelt. Jetzt ist meine Frage welche die bessere Performance hat und ob sich der Aufwand überhaupt gelohnt hätte (Hätte mich das Thema nicht einfach mal interessiert). Ein Profiler kann ich schwer nutzen da es sich um ein Plugin für Spigot (Minecraft Server) handelt. Vllt könnt ihr mir ja auch so weiterhelfen 🙂 Edit: Was ich vergessen hatte anzumerken ist, das data.getCoLeader bzw data.getMember bei jedem aufruf eine ganze Config aus einer HashMap läd und aus dieser eine bestimmte StringListe zurückgibt.
[CODE lang="java" title="ohne optimierung"]public List<String> getClanInfo(String clan) {
List<String> info = new ArrayList<String>();
List<String> membernames = new ArrayList<String>();
List<String> coleadernames = new ArrayList<String>();
String friendlyfire;

for(String uuid : data.getCoLeaders(clan)) {
coleadernames.add(Bukkit.getOfflinePlayer(UUID.fromString(uuid)).getName());
}

for(String uuid : data.getMembers(clan)) {
membernames.add(Bukkit.getOfflinePlayer(UUID.fromString(uuid)).getName());
}

if(Boolean.valueOf(data.getClanData(clan, "friendlyfire").toString()) == true) {
friendlyfire = "§cenable";
}else {
friendlyfire = "§adisable";
}

info.add(messages.getPrefix() + "§6----------------ClanInfo---------------");
info.add(messages.getPrefix() + "§8name: §7" + clan);
info.add(messages.getPrefix() + "§8description: §7" + data.getClanData(clan, "description"));
info.add(messages.getPrefix() + "§8leader: §7" + Bukkit.getOfflinePlayer(UUID.fromString(data.getClanData(clan, "leader").toString())).getName());
info.add(messages.getPrefix() + "§8friendlyfire: " + friendlyfire);
info.add(messages.getPrefix() + "§8public: §7" + data.isPublic(clan));
info.add(messages.getPrefix() + "§8coleader: §7" + coleadernames);
info.add(messages.getPrefix() + "§8members: §7" + membernames);
info.add(messages.getPrefix() + "§6----------------ClanInfo---------------");
return info;[/CODE]

[CODE lang="java" title="mit optimierung"]public String[] getClanInfo(String clan) {
final String[] info = new String[9];
final String[] coleader_uuids = data.getCoLeaders(clan).toArray(new String[0]);
final String[] member_uuids = data.getMembers(clan).toArray(new String[0]);
final String[] membernames = new String[member_uuids.length];
final String[] coleadernames = new String[coleader_uuids.length];
String friendlyfire;

final int j_coleader = coleader_uuids.length;
for(int i = 0; i < j_coleader; i++) {
coleadernames = Bukkit.getOfflinePlayer(UUID.fromString(coleader_uuids)).getName();
}

final int j_member = member_uuids.length;
for(int i = 0; i < j_member; i++) {
membernames = Bukkit.getOfflinePlayer(UUID.fromString(member_uuids)).getName();
}

if((Boolean)data.getClanData(clan, "friendlyfire") == true) {
friendlyfire = "§cenable";
}else {
friendlyfire = "§adisable";
}

info[0] = messages.getPrefix() + "§6----------------ClanInfo---------------";
info[1] = messages.getPrefix() + "§8name: §7" + clan;
info[2] = messages.getPrefix() + "§8description: §7" + data.getClanData(clan, "description");
info[3] = messages.getPrefix() + "§8leader: §7" + Bukkit.getOfflinePlayer(UUID.fromString(data.getClanData(clan, "leader").toString())).getName();
info[4] = messages.getPrefix() + "§8friendlyfire: " + friendlyfire;
info[5] = messages.getPrefix() + "§8public: §7" + data.isPublic(clan);
info[6] = messages.getPrefix() + "§8coleader: §7" + Arrays.toString(coleadernames);
info[7] = messages.getPrefix() + "§8members: §7" + Arrays.toString(membernames);
info[8] = messages.getPrefix() + "§6----------------ClanInfo---------------";
return info;
}[/CODE]
 
String Array ist sicher schneller als ArrayList<String>.
Definiere schneller. Ich behaupte nein, es ist nicht schneller in einem praktischen Sinne.

Hier mal ein sehr alter Stackoverlow beitrag:
Although the answers proposing to use ArrayList do make sense in most scenario, the actual question of relative performance has not really been answered.

There are a few things you can do with an array:

  • create it
  • set an item
  • get an item
  • clone/copy it

General conclusion​

Although get and set operations are somewhat slower on an ArrayList (resp. 1 and 3 nanosecond per call on my machine),

Eine Arraylist, die man direkt mit der richtigen Größe spezifiziert ist nicht sinnvoll messbar langsamer.
 
Also die Zugriffe sind bei beidem (Array und ArrayList) O(1), denn die ArrayList hat auch nur eine Array. Daher ist da nur ein minimaler Overhead durch die Zugriffe weil da paar Befehle drumherum sind.

Und beim Einfügen kann es zu zusätzlichem Aufwand kommen, da ein neues, größeres Array erstellt werden muss.

Aber die Diskussion ist nicht wirklich zielführend. Hier wird eine Optimierung besprochen. Zu Optimierungen kann ich nur sagen:
Rules of Optimization:
Rule 1: Don’t do it.
Rule 2 (for experts only): Don’t do it yet.

Daher: praktisch gewinnst Du nichts an Performance. Wenn diese Optimierung wichtig war, dann hast Du ein generelles Design-Problem! Da geht es um minimale Unterschiede - da wäre dann die Frage: Wenn Do so harte Anforderungen hast: Ist das nicht schon eine Anforderung, da RT Lösungen zu bauen? Oder wenigstens eine Lösung, wo andere Threads nicht plötzlich Performance brauchen (z.B. der GC)

Und wenn Performance optimiert werden müsste, dann wäre immer die Frage: Kann ich die Logik verändern? Also ich könnte darauf verzichten, dass die da jetzt diese Listen erzeuge, weil ich sicher stelle, dass die Informationen immer direkt nutzbar vorliegen. (Dann spart man hier, aber es kostet ggf mehr, Daten zu ändern ... ==> Ohne Analyse und genaue Anforderungen keine Optimierung!)

Edit: "(Array und ArrayList)" eingefügt im ersten Satz - denn darum geht es. Die Methoden selbst haben natürlich kein O(1) 🙂
 
Zuletzt bearbeitet von einem Moderator:
Bei Optimierungen sollte man immer folgendermassen vorgehen:

1. das gesamte Programm (nicht nur diese eine kleine Methode) unter Realbedingungen messen!
2. eventuelle Performanceengpässe anhand der Messdaten identifizieren, die auch einen nennenswerten Anteil an der Gesamtlaufzeit haben)
3. mögliche Anpassungen für eine eventuelle Optimierung identifizieren
4. Anpassungen einbauen
5. nochmal das gesamte Programm unter Realbedingungen messen
6. validieren, ob die Optimierung für das Programm überhaupt etwas gebracht hat
7. feststellen, dass das nicht der Fall war

Man _kann_ durchaus optimieren. Aber man sollte sich vorher darüber im Klaren sein, welches Ziel man damit genau erreichen möchte. Nur eine einzige Methode (unter vielen hunderten anderer Methoden im Callstack) isoliert zu betrachten, bringt höchstwarhscheinlich nichts, durch die vielen Intra-Methoden-Optimierungen der JVM (inlining, escape analysis, stack replacement), die im Zusammenspiel mit dem gesamten Callstack ganz andere Effekte haben können.

Alles steht und fällt aber eben mit einer korrekten Messmethodik, die eben für das betrachtete Programm auch eine Aussage darüber treffen kann, ob die Performanceoptimierungen überhaupt etwas gebracht haben.
 
ich wollte allgemein nur mal schauen wie das so in Java ist alles. Deswegen auch nur diese eine Methode, es war nur zum testen und aus spaß. Ich werde mein Code nicht optimieren da es nicht sinnvoll ist. Wollte nur mal so schauen, ob das nen Unterschied machen würde. Trotzdem danke für alle Antworten 🙂
 
Definiere praktisch.
So, dass es messbar im Gesamtprogramm was bringt. Wie schon von den Vorrednern geschrieben - Performance Optimierungen ohne das eine sinnvolle Messmethodik habe, sind meist kontraproduktiv.

Und die Stelle zu optimieren bringt - bezogen auf das Gesamtprogramm - nichts, das geht im Rauschen und der Messungenauigkeit drunter. Das ist so sinnvoll wie bei einem 40-Tonner ein Milligramm an Gewicht durch Verwendung eines anderen Sitzbezuges zu sparen um damit Sprit zu sparen.
 

Ich glaube, zum Thema Optimieren in Hochsprachen sollte man mal etwas ausführlicheres schreiben, damit weniger angehende Entwickler weniger Zeit vertrödeln.
 
Also die Zugriffe sind bei beidem (Array und ArrayList) O(1), denn die ArrayList hat auch nur eine Array. Daher ist da nur ein minimaler Overhead durch die Zugriffe weil da paar Befehle drumherum sind.

Und beim Einfügen kann es zu zusätzlichem Aufwand kommen, da ein neues, größeres Array erstellt werden muss.

Aber die Diskussion ist nicht wirklich zielführend. Hier wird eine Optimierung besprochen. Zu Optimierungen kann ich nur sagen:


Daher: praktisch gewinnst Du nichts an Performance. Wenn diese Optimierung wichtig war, dann hast Du ein generelles Design-Problem! Da geht es um minimale Unterschiede - da wäre dann die Frage: Wenn Do so harte Anforderungen hast: Ist das nicht schon eine Anforderung, da RT Lösungen zu bauen? Oder wenigstens eine Lösung, wo andere Threads nicht plötzlich Performance brauchen (z.B. der GC)

Und wenn Performance optimiert werden müsste, dann wäre immer die Frage: Kann ich die Logik verändern? Also ich könnte darauf verzichten, dass die da jetzt diese Listen erzeuge, weil ich sicher stelle, dass die Informationen immer direkt nutzbar vorliegen. (Dann spart man hier, aber es kostet ggf mehr, Daten zu ändern ... ==> Ohne Analyse und genaue Anforderungen keine Optimierung!)

Edit: "(Array und ArrayList)" eingefügt im ersten Satz - denn darum geht es. Die Methoden selbst haben natürlich kein O(1) 🙂
also bringt es an sich wenig, Java Programme zu optimieren?
 
also bringt es an sich wenig, Java Programme zu optimieren?
Generell bringt eine Optimierung wenig. Wenn es ein Problem gibt, dann muss man das Problem analysieren um dann das Problem selbst lösen zu können.

Aber so blinde Optimierungen bringen nichts, daher sollte man davon die Finge lassen. Da ist die Gefahr eher gegeben, dass man unleserlichen Code schreibt.

Aber man sollte seine Werkzeuge kennen, also z.B. die ganzen Collections. So kann man brauchbare Collections für die notwendigen Operationen auswählen. Mann kann auch uneffektive Dinge bleiben lassen. Das wäre dann das Buch "Effective Java", das ich empfehlen würde.
Aber ganz wichtig: Da geht es nicht um eine Optimierung, damit Code schneller läuft sondern da geht es einfach nur generell darum, wie man besseren Code schreiben kann.
 

Neue Themen


Zurück
Oben