performance-optimierung mit und ohne android developer tools · performance - optimierung mit und...

Post on 03-Aug-2020

7 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Performance - Optimierung

mit und ohne Android Developer Tools

Dominik Helleberg

Köln - 25.09.2014

2

Performance

Analysieren

Verstehen

Fixen

3

Performance-Probleme... Netzwerk / Cache

4

Performance-Probleme... Netzwerk / Cache

5

Performance-Probleme... Netzwerk / Cache

6

Performance-Probleme... Netzwerk / Cache

7

Performance-Probleme... User Interface

8

Performance-Probleme... User Interface

https://flic.kr/p/6MVMJi grrr | sookie

9

Performance Probleme Grrrrrr

https://flic.kr/p/6oLD5r Tacho | Thaddäus Zoltkowski

10

Performance messen Laufzeiten

11

Performance messen Laufzeiten

Log !long start = System.nanoTime(); !!/** Do things.... */ !!Log.d(TAG, “Doing took” +(System.nanoTime()-start)); !

12

Performance messen Laufzeiten

Timing Logger !

TimingLogger timings = new TimingLogger(TAG, "mURL"); !/** Do cache */ !timings.addSplit(“cache"); !/** Do load */ !timings.addSplit(“load"); !/** and scale! */ !timings.addSplit(“scale"); !timings.dumpToLog(); !

$> adb shell setprop log.tag.TTTask VERBOSE !

TTTask D mURL: begin ! D mURL: 4 ms, cache ! D mURL: 1819 ms, load ! D mURL: 8 ms, scale ! D mURL: end, 1831 ms !

13

Performance messen Laufzeiten

Hugo !apply plugin: 'hugo‘ !!classpath 'com.jakewharton.hugo:hugo-plugin:1.1.+‘ !!!

import hugo.weaving.DebugLog; !!@DebugLog !protected Bitmap doInBackground(Void... arg0) { !!} !

" " " D ⇢ doInBackground(arg0=null) !!Activity$ThumbnailTask D ⇠ doInBackground [1015ms] = !

" " "android.graphics.Bitmap@b187ec38 !

14

Performance messen Laufzeiten

Traceview!

15

Performance messen Laufzeiten

Traceview!

16

Performance messen Laufzeiten

Systrace ab API Level 16 (4.1) !

17

Performance messen Laufzeiten

Systrace ab API Level 18 (4.3) !

             systrace  -­‐t  20  -­‐b  10000  gfx  input  view  sched  freq  -­‐a  de.inovex.samples  

Trace.beginSection("bind-view"); !!/*do things ... */ !!!Trace.endSection(); !!!

18

Performance messen Frames

http://www.curious-creature.org/docs/android-performance-case-study-1.html 19

Performance messen Frames

(Blau) Draw is the time spent building display lists in Java. It indicates how much time is spent running methods such as View.onDraw(Canvas).

http://www.curious-creature.org/docs/android-performance-case-study-1.html 20

Performance messen Frames

(ROT) Process is the time spent by Android’s 2D renderer to execute the display lists. The more Views in your hierarchy, the more drawing commands must be executed.

http://www.curious-creature.org/docs/android-performance-case-study-1.html 21

Performance messen Frames

(Orange) Execute is the time it took to send a frame to the compositor. This part of the graph is usually small.

22

Beispiel App - flickr

23

Beispiel App - Anforderung

24

Beispiel App - Implementierung

•  flickr API http://ycpi.api.flickr.com/services/feeds/photos_public.gne?tags=berlin

<entry> ! <title>Balkonien, Berlin, 2014.</title> ! <link rel="alternate" type="text/html" href="http://www.flickr.com/photos/schommsen/14968952316/"/> ! <id>tag:flickr.com,2005:/photo/14968952316</id> ! <published>2014-08-21T18:36:13Z</published> ! <updated>2014-08-21T18:36:13Z</updated> ! <author> ! <name>schommsen</name> ! <uri>http://www.flickr.com/people/schommsen/</uri> ! <flickr:buddyicon>http://farm4.staticflickr.com/3759/buddyicons/ 34398594@N04.jpg?1378603265#34398594@N04</flickr:buddyicon> ! </author> ! <link rel="enclosure" type="image/jpeg" href="http://farm6.staticflickr.com/5581/14968952316_f9bb0999d2_b.jpg" /> !.... !!!!

25

Beispiel App - Implementierung View-Item

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ! android:layout_width="match_parent“ android:layout_height="match_parent“> ! <ImageView! android:id="@+id/fli_picture_imageview" ! android:layout_width="280dp" ! android:layout_height="280dp" ! android:layout_centerVertical="true" ! android:layout_centerHorizontal="true" /> ! <ImageView! android:layout_width="40dp" ! android:layout_height="40dp" ! android:id="@+id/fli_authorPic_imageview" ! android:layout_alignParentBottom="true" ! android:layout_alignParentLeft="true" /> ! <TextView ! android:id="@+id/fli_title_textview" ! android:layout_alignParentTop="true" ! android:layout_alignParentLeft="true" /> ! <TextView ! android:textAppearance="?android:attr/textAppearanceSmall“ ! android:id="@+id/fli_date_textview" ! android:layout_alignParentRight="true" ! android:layout_alignParentBottom="true" /> !!</RelativeLayout> !

26

Beispiel App - Implementierung Adapter

@Override !public View getView(int position, View convertView, ViewGroup parent) { !! View view = mInflater.inflate(R.layout.flickr_item_list_entry, parent, false); ! ! ImageView imageView = (ImageView) view.findViewById(R.id.fli_picture_imageview); ! ImageView authorPic = (ImageView) view.findViewById(R.id.fli_authorPic_imageview); ! TextView dateTaken = (TextView) view.findViewById(R.id.fli_date_textview); ! TextView title = (TextView) view.findViewById(R.id.fli_title_textview); !! title.setText(flickrFeedEntry.title); !! Date nowDate = new Date(); ! nowDate.setTime(nowDate.getTime() - flickrFeedEntry.dateTaken.getTime()); ! SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd"); ! dateTaken.setText(simpleDateFormat.format(nowDate) + " Days ago"); !! // ToDo: Image Loading ! return view; !} !!!

27

Beispiel App - Implementierung Adapter – Image Loading

!new ThumbnailTask(position, url,imageView).executeOnExecutor(mExecutor, null); !!!!

•  Async Task? Don‘t even think about it!

•  Picasso Picasso.with(getContext()).load(flickrFeedEntry.imageURL).transform(new CropSquareTransformation()).into(imageView); !!Picasso.with(getContext()).load(flickrFeedEntry.authorIconURI).transform(new CropSquareTransformation()).into(authorPic); !!

28

Beispiel App - Demo

29

Beispiel App - Implementierung Adapter

public View getView(int position, View convertView, ViewGroup parent) { !! View view = mInflater.inflate(R.layout.flickr_item_list_entry, parent, false); ! ! ImageView imageView = (ImageView) view.findViewById(R.id.fli_picture_imageview); ! ImageView authorPic = (ImageView) view.findViewById(R.id.fli_authorPic_imageview); ! TextView dateTaken = (TextView) view.findViewById(R.id.fli_date_textview); ! TextView title = (TextView) view.findViewById(R.id.fli_title_textview); !! // Image loading here !! title.setText(flickrFeedEntry.title); !! Date nowDate = new Date(); ! nowDate.setTime(nowDate.getTime() - flickrFeedEntry.dateTaken.getTime()); ! SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd"); ! dateTaken.setText(simpleDateFormat.format(nowDate) + " Days ago"); !! return view; !} !!!

30

Analyse – 1 getView

TimingLogger timings = new TimingLogger(TAG, “getView"); !!view = mInflater.inflate(R.layout.flickr_item_list_entry, parent, false); !//... !!timings.addSplit(“find/inflate"); !!//Picasso.with... !!timings.addSplit(“picasso"); !!//textView.setText(...) !!timings.addSplit(“filldata"); !timings.dumpToLog(); !

31

Analyse – 1 getView

D getView: begin !D getView: 4 ms, find/inflate !D getView: 1 ms, picasso !D getView: 1 ms, filldata!D getView: end, 6 ms !!D getView: begin !D getView: 2 ms, find/inflate !D getView: 0 ms, picasso !D getView: 2 ms, filldata!D getView: end, 4 ms !!D getView: begin !D getView: 5 ms, find/inflate !D getView: 1 ms, picasso !D getView: 0 ms, filldata!D getView: end, 6 ms !!

32

Analyse – 1 getView - traceview

33

Analyse – 1 getView - optimiert

public View getView(int position, View convertView, ViewGroup parent) { ! View view = convertView; ! if(view == null) { ! view = mInflater.inflate(R.layout.flickr_item_list_entry, parent, false); ! ViewHolder viewHolder = new ViewHolder(); !! viewHolder.imageView = (ImageView)view.findViewById(R.id.fli_picture_imageview); ! //... ! view.setTag(viewHolder); ! } ! ViewHolder viewHolder = (ViewHolder) view.getTag(); !! //picasso loading... !! viewHolder.title.setText(flickrFeedEntry.title); ! mNowDate.setTime(System.currentTimeMillis() - "

"flickrFeedEntry.dateTaken.getTime()); ! viewHolder.dateTaken.setText(mSimpleDateFormat.format(mNowDate) + DAYS); !! return view; !} !!!

34

App v2 getView - optimiert

35

App v2 getView - optimiert

D getView: 6 ms, find/inflate ! D getView: 0 ms, picasso ! D getView: 1 ms, filldata! D getView: end, 7 ms !! D getView: begin ! D getView: 0 ms, find/inflate ! D getView: 0 ms, picasso ! D getView: 0 ms, filldata! D getView: end, 0 ms !! D getView: begin ! D getView: 0 ms, find/inflate ! D getView: 0 ms, picasso ! D getView: 1 ms, filldata! D getView: end, 1 ms !!

36

App v2 Analyse - Systrace

$> systrace -a de.inovex.samples gfx input view dalvik res sched !

37

App v2 Analyse - Logcat

dalvikvm D GC_FOR_ALLOC freed 5077K, 30% free 19358K/27632K, paused 20ms, total 20ms !! D GC_FOR_ALLOC freed 71K, 19% free 22504K/27632K, paused 16ms, total 16ms !!dalvikvm-heap I Grow heap (frag case) to 25.011MB for 3145744-byte allocation !! dalvikvm D GC_FOR_ALLOC freed 0K, 17% free 25576K/30708K, paused 21ms, total 21ms!

38

App v2 Analyse – Bild-Größen

<link rel="enclosure" type="image/jpeg" href="http://farm6.staticflickr.com/5581/14968952316_f9bb0999d2_b.jpg" /> !!$> curl http://farm6.staticflickr.com/5581/14968952316_f9bb0999d2_b.jpg > out.jpg !!$> identify out.jpg !out.jpg JPEG 600x900 600x900+0+0 8-bit sRGB 183KB 0.000u 0:00.000!

Speicher: 600 x 900 x 4 = 2.2 Megabytes 4 Zeilen à 2 Bilder: ~ 18 MBytes

$> getprop dalvik.vm.heapgrowthlimit!64m !

39

App v2 Analyse – Bild-Größen – Flickr - Doku

https://www.flickr.com/services/api/misc.urls.html!s "small square 75x75 !q "large square 150x150 !t "thumbnail, 100 on longest side !m "small, 240 on longest side !n "small, 320 on longest side !- "medium, 500 on longest side !z "medium 640, 640 on longest side !c "medium 800, 800 on longest side† !b "large, 1024 on longest side* !

40

App v3 Wie groß ist mein ImageView?

int size = Math.max(imageView.getWidth(), imageView.getHeight()); !!

Invalidate Measure & Layout Draw

0,0 320,300

41

App v3 Wie groß ist mein ImageView?

final ViewTreeObserver viewTreeObserver = mGridView.getViewTreeObserver(); !viewTreeObserver.addOnPreDrawListener( !

"new ViewTreeObserver.OnPreDrawListener() { ! @Override ! public boolean onPreDraw() { !

" "if(viewTreeObserver.isAlive()) ! viewTreeObserver.removeOnPreDrawListener(this); !

" "//do things !" "return true; !

} ! }); !

Invalidate Measure & Layout Draw

42

App v3 Wie groß ist mein ImageView?

public class MyImageView extends ImageView { !! @Override! protected void onSizeChanged(int w, int h, int oldw, int oldh) { ! super.onSizeChanged(w, h, oldw, oldh); !

"//use w and h ! } !!!

Invalidate Measure & Layout Draw

43

App v3 Wie groß ist mein ImageView?

!imageView.post(new Runnable() { ! @Override ! public void run() { !

"//Do things ! } !}); !!

Invalidate Measure & Layout Draw

44

App v3 Bilder optimiert

45

App v3 Done?

https://flic.kr/p/nqwvF Flensburger Pilsner | fleno.de

DONE?

Not yet...

46

App v3 Response Cache (API Level 13)

protected void onCreate(Bundle savedInstanceState) { !... ! try { ! File httpCacheDir = new File(context.getCacheDir(), "http"); ! long httpCacheSize = 10 * 1024 * 1024; // 10 MiB ! HttpResponseCache.install(httpCacheDir, httpCacheSize); ! } ! catch (IOException ex) { ! Log.i(TAG, "HTTP response cache installation failed:" + ex); ! } !}!protected void onStop() { ! super.onStop(); ! HttpResponseCache cache = HttpResponseCache.getInstalled(); ! if (cache != null) { ! cache.flush(); ! } !} !!

47

App v3 Cache?

48

App v3 Prost!

https://flic.kr/p/nqwvF Flensburger Pilsner | fleno.de

49

Performance Tipps + Tricks Flache Layout-Hierarchien -> Hierarchy Viewer

https://github.com/JakeWharton/scalpel 50

Performance Tipps + Tricks Flache Layout-Hierarchien -> Scalpel

http://www.sriramramani.com/droidinspector/ 51

Performance Tipps + Tricks Flache Layout-Hierarchien -> Droid Inspector

TODO: URL 52

Performance Tipps + Tricks Overdraw

53

Performance Tipps + Tricks Garbarge Collection -> zu viele Objekte? -> Allocation Tracker

54

Immer 60 FPS

Danke!

top related