Um aktiv im Android Forum teilnehmen zu können, musst Du Dich bei AndroidPIT registriert haben.
Benjamin Rühl ![]() Rang: Schülersprecher Beiträge: 95 Eintrittsdatum: 15.12.2009 |
Threads und deren Performance verfasst am 08.03.2010 15:01:00
Hi Ihrs,
ich hab mal ne generelle Frage. Ich programmiere gerade an einer App und würde sie gerne in der Performance ein bischen verbessern. Bisher werden in einer Liste neben Informationen noch viele Bilder angezeigt. Diese Bilder werden in einem extra Thread nachgeladen. Jetzt merke ich, dass das Scrollen durch die Liste während des Nachladens der Bilder stockt. Sobald ale Bilder geladen wurden ruckelt das Scrollen nicht mehr. Nun zu meiner Frage: Kann man einem Thread weniger CPU-Power zuweisen, sodass dieser zwar langsamer ausgeführt wird dafür den Thread für das UserInterface aber nicht behindert? Kennt ihr da Möglichkeiten? MfG Benjamin |
Markus Gu ![]() Rang: Android Gottheit Beiträge: 2.528 Eintrittsdatum: 05.06.2009 |
RE: Threads und deren Performance verfasst am 08.03.2010 15:03:59
threads kann man sicher nicht langsamer ausführen.
der ui thread wird aber auch nicht durch deinen thread behindert. es passiert in wirklichkeit ja genau nichts gleichzeitig. die threads wechseln sich ab. einmal der - einmal der. die, die nicht laufen, werden angehalten. dein problem liegt eher wo anders, denke ich. |
Jörg V. ![]() Status: Administrator Rang: Android Gottheit Beiträge: 4.914 Eintrittsdatum: 08.06.2009 |
RE: Threads und deren Performance verfasst am 08.03.2010 17:23:54
Ich würde während des Nachladens der Bilder mal den Speicherverbrauch der App ein wenig unter die Lupe nehmen.
Eventuell verbrauchst Du ungewollter Weise viel Speicher durch unnötig angelegte und nicht dereferenzierte Objekte ... Dann schlägt u.U. der Garbage Collector zu und muss aufräumen. Das Problem dabei ist, dass in dem Moment der Garbage Collector anläuft, alle anderen Threads gestoppt werden. Ob der Garbage Collector während der Ausführung zündet sollte Dir eine Logcat Ausgabe während des Laufes bereits zeigen.
----- |
Benjamin Rühl ![]() Rang: Schülersprecher Beiträge: 95 Eintrittsdatum: 15.12.2009 |
RE: Threads und deren Performance verfasst am 08.03.2010 18:10:48 — geändert am 08.03.2010 18:11:00
Danke für die Hilfe.
Der Garbage Collector springt immer genau 2 mal an: 1. wenn die Daten der Liste durch Nachladen erweitert wurde und "notifyDataSetChanged()" aufgerufen wird 2. wenn ich anfange die Liste nach unten zu scrollen Das wiederholt sich dann jedesmal wenn die Liste ganz nach unten gescrollt und weitere Daten nachgeladen und angezeigt werden. Dachte bisher, dass das ein normales Verhalten ist, da beim Scrollen oder bearbeiten von nachgeladenen Daten relativ viele Objekte erstellt werden. Ist dem nicht so? |
Jörg V. ![]() Status: Administrator Rang: Android Gottheit Beiträge: 4.914 Eintrittsdatum: 08.06.2009 |
RE: Threads und deren Performance verfasst am 08.03.2010 20:08:22
Das der garbage collector anläuft ist per se nichts schlimmes.
Aber ... man muss ihm die Arbeit ja nicht unnötig schwer machen und unnötig Objekte erzeugen die er dann wieder vom Heap herunterräumen muss. Darüber hinaus kann man schonend mit Speicher umgehen. Je weniger Speicher der GC durchackern muss, um so schneller ist er fertig. Einfaches Beispiel: 1String s = ""; 2for (Person p : persons) { 3 s += ", " + p.getName(); 4} Der Code schaut auf den ersten Blick relativ normal aus, ist aber ein absolutes Java Antipattern ... und ein absoluter Performance Killer. Soweit klar warum ?
----- |
Markus Gu ![]() Rang: Android Gottheit Beiträge: 2.528 Eintrittsdatum: 05.06.2009 |
RE: Threads und deren Performance verfasst am 08.03.2010 20:21:33 |
Jörg V. ![]() Status: Administrator Rang: Android Gottheit Beiträge: 4.914 Eintrittsdatum: 08.06.2009 |
RE: Threads und deren Performance verfasst am 08.03.2010 20:47:21
Einerseits hast Du recht Markus, andererseits sind es genau solche vermeintlich harmlosen Codesnippets die immer wieder dafür sorgen, dass die Mär vom LANGSAMEN Java im Volke Verbreitung findet.
----- |
Benjamin Rühl ![]() Rang: Schülersprecher Beiträge: 95 Eintrittsdatum: 15.12.2009 |
RE: Threads und deren Performance verfasst am 09.03.2010 09:11:05 — geändert am 09.03.2010 09:12:21 Jörg Voss Das der garbage collector anläuft ist per se nichts schlimmes. Aber ... man muss ihm die Arbeit ja nicht unnötig schwer machen und unnötig Objekte erzeugen die er dann wieder vom Heap herunterräumen muss. Darüber hinaus kann man schonend mit Speicher umgehen. Je weniger Speicher der GC durchackern muss, um so schneller ist er fertig. Einfaches Beispiel: 1String s = ""; 2for (Person p : persons) { 3 s += ", " + p.getName(); 4} Der Code schaut auf den ersten Blick relativ normal aus, ist aber ein absolutes Java Antipattern ... und ein absoluter Performance Killer. Soweit klar warum ? Auch auf die Gefahr dass ich mich blamiere, so hätte ich es gemacht: [code] StringBuffer sb = new StringBuffer(); Person[] persons; int length = persons.length; for(int i=0; i<length; i++){ sb.append(persons[i].name); } [/code] - StringBuffer weil ich gelernt habe, dass das dynamische Erstellen von Strings mit hilfe von Stringbuffern die performanteste Lösung ist - name als public weil es in den Performance Guidlines von Android steht. NIcht hübsch aber schneller. Richtig, falsch? |
Jörg V. ![]() Status: Administrator Rang: Android Gottheit Beiträge: 4.914 Eintrittsdatum: 08.06.2009 |
RE: Threads und deren Performance verfasst am 09.03.2010 19:13:59
Hallo Benjamin,
vorweg, die bessere Lösung bezogen auf mein eingehendes Beispiel wäre eigentlich diese hier: 1StringBuilder sb = new StringBuilder(persons.size() * 16); // well estimated buffer 2for (Person p : persons) { 3 if (sb.length() > 0) sb.append(", "); 4 sb.append(p.getName); 5 6} Zunächst warum StringBuilder und nicht StringBuffer? StringBuffer hat eine implizite Synchronisation die hier Overkill wäre bei der lokalen Variable. Die zusätzliche Größendefinition von StringBuilder schafft zusätzlich Performance weil nicht so schnell vergrößert werden muss. Strings sind immutable Object, also unveränderlich, somit würde bei der permanenten Concatenation ständig neue Objekte angelegt werden, da das eigetnliche ja nicht verändert werden kann. Deswegen sammelt sich viel Garbage an der dann vom GC fortgeräumt werden muss, was wiederum tierisch Zeit kostet.
----- |
Benjamin Rühl ![]() Rang: Schülersprecher Beiträge: 95 Eintrittsdatum: 15.12.2009 |
RE: Threads und deren Performance verfasst am 09.03.2010 20:26:58
Interessant. Und warum berrechnest du die Größe des StrungBuilders indem du die Anzahl der Felder mit 16 multiplizierst? Dann dürften die Namen durchschnittlich nicht länger als 16 Zeichen sein, oder?
Benutzt man StringBuilder eigentlich auch bei einfachen Verkettungen wie 1String s = "Text text text text"; 2s += "noch mehr text"; ? Also bei einer einfachen Verkettung? |
Jörg V. ![]() Status: Administrator Rang: Android Gottheit Beiträge: 4.914 Eintrittsdatum: 08.06.2009 |
RE: Threads und deren Performance verfasst am 10.03.2010 00:47:34 Benjamin R. Interessant. Und warum berrechnest du die Größe des StrungBuilders indem du die Anzahl der Felder mit 16 multiplizierst? Dann dürften die Namen durchschnittlich nicht länger als 16 Zeichen sein, oder? Benutzt man StringBuilder eigentlich auch bei einfachen Verkettungen wie 1String s = "Text text text text"; 2s += "noch mehr text"; ? Also bei einer einfachen Verkettung? Die initiale Größe von StringBuilder ist 16 ... bzw. Länge des Strings plus 16. Für einzelne Verkettungen ist es wohl schneller einfach eine simple Concatenation zu verwenden. Dabei wird einfach der effektivere Bytecode generiert. Sobald es Wiederholungen gibt .. den Builder verwenden.
----- |
Benjamin Rühl ![]() Rang: Schülersprecher Beiträge: 95 Eintrittsdatum: 15.12.2009 |
RE: Threads und deren Performance verfasst am 10.03.2010 10:31:54
Ok, danke.
Ich fände es sehr praktisch wenn es eine Übsersicht über genau solche Beispiele geben würde. Woher soll ein Java-Entwickler, der bisher nicht auf Performance achten musste, sonst wissen wie er performant für Android entwickelt. Gibt es sowas nicht zufällig? Kennst du eine Übersicht über all die Klassen die eine Synchronisation bieten? Ich frage weil ich zum Beispiel in mehreren Threads mehrere Bilder nachlade und alle Bilder in einer HashMap ablegen möchte, als cache sozusagen. Dazu muss die HashMap allerdings synchronisiert werden. Wo kann ich nachlesen welche Klassen schon von Haus aus Synchronisation bieten? |
Mac Systems ![]() Rang: Android SilverSenior Beiträge: 966 Eintrittsdatum: 21.06.2009 |
RE: Threads und deren Performance verfasst am 10.03.2010 13:47:30
In der API Doc zum Beispiel.
Eine HashMap ist der nicht synchronisierte Pendant zu einer HashTable aber beide Implmenetieren ein Map Interface. Gleiches gilt für Vector vs. ArrayList. Es gibt zu dem Thema Bücher z.b "Java Threads" von OReily welches das JDK 5 beschreibt Android ist hier also abgedeckt. Weiterhin gibt es Performance Bücher zu Java. Mit Java 7 bekommen die Collection Classes noch Neuerungen, zwar werden wir die in Android erstmal nicht sehen dennoch sehr interessante Dinge für nebenläufige Programmierung.
----- |