Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Android Performance Matters - Ran Nachmany, Google

1,344 views

Published on

As presented in DroidCon Tel Aviv 2015
http://il.droidcon.com

Published in: Technology

Android Performance Matters - Ran Nachmany, Google

  1. 1. Performance Matters +Ran Nachmany @shed2k
  2. 2. Battery Performance Hey, do you have a power outlet I can use?
  3. 3. I’m doing stuff! LOL! NOPE.
  4. 4. What’s eating your mobile battery? goo.gl/nMkSE 25-30%Actual work. 70%Analytics GPS Ads
  5. 5. QUIT BEING STUPID. Better Battery Golden Rule
  6. 6. DEFER WORK UNTIL THE BEST TIME FOR BATTERY Better Battery Golden Rule
  7. 7. Battery Problem: WakeLocks
  8. 8. Active Screen Off Z Z Z Asleep
  9. 9. Keeping the device awake goo.gl/uEfy56 Z Z Z Wakelock
  10. 10. Wakelock.aquire(..) goo.gl/ZNCx6n
  11. 11. AlarmManager.setInexact*(..) goo.gl/l7m7fb20 minutes 15 minutes
  12. 12. Release Wakelocks. Batch Wakeups. #PERFMATTERS TIP
  13. 13. Battery Problem: Location
  14. 14. EXPENSIVE
  15. 15. GPS Provider Cell Network Provider More Accurate More Power Less Accurate Less Power
  16. 16. Better Accuracy Better Battery PRIORITY_HIGH_ACCURACY PRIORITY_BALANCED_POWER_ACCURACY PRIORITY_LOW_POWER PRIORITY_NO_POWER What’s the best State for right now?
  17. 17. Z Z Z PRIORITY_HIGH_ACCURACY PRIORITY_BALANCED_POWER_ACC URACY PRIORITY_LOW_POWER PRIORITY_NO_POWER
  18. 18. GPS Fetch Totally steal Passive Provider
  19. 19. Only use the resolution you need. #PERFMATTERS TIP #43
  20. 20. Networking
  21. 21. Battery Drain
  22. 22. Bandwidth Power Idle DCH FACH
  23. 23. Bandwidth Power Idle DCH FACH Tail Time ~10 sec Tail Time ~60 sec Wake Up Time ~2 Sec
  24. 24. $$$$$$$$$ User Pays for your requests
  25. 25. LESS RADIO TIME LESS DATA NETWORKING Golden Rule
  26. 26. Network Technique: Batching
  27. 27. XHR wait XHR wait XHR wait XHR wait XHR wait XHR wait XHR XHR XHR XHR XHR XHR wait BATCHING!
  28. 28. Do Now Server Response Data Push Types of networking requests CAN OPTIMIZE
  29. 29. requests pending queue
  30. 30. Length == 10 pending queue requests
  31. 31. Get Notified
  32. 32. Get Notified
  33. 33. JobInfo uploadJob = new JobInfo.Buildr(mSomeInt, mServiceComponent) .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) .setOverrideDeadline(DateUtils.HOUR_IN_MILLIS) .setRequiresCharging(true) .build(); JobScheduler API
  34. 34. JobInfo uploadJob = new JobInfo.Buildr(mSomeInt, mServiceComponent) .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) .setOverrideDeadline(DateUtils.HOUR_IN_MILLIS) .setRequiresCharging(true) .build(); JobScheduler API JobId
  35. 35. JobInfo uploadJob = new JobInfo.Buildr(mSomeInt, mServiceComponent) .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) .setOverrideDeadline(DateUtils.HOUR_IN_MILLIS) .setRequiresCharging(true) .build(); JobScheduler API Job Endpoint
  36. 36. JobInfo uploadJob = new JobInfo.Buildr(mSomeInt, mServiceComponent) .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) .setOverrideDeadline(DateUtils.HOUR_IN_MILLIS) .setRequiresCharging(true) .build(); JobScheduler API Network Type
  37. 37. JobInfo uploadJob = new JobInfo.Buildr(mSomeInt, mServiceComponent) .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) .setOverrideDeadline(DateUtils.HOUR_IN_MILLIS) .setRequiresCharging(true) .build(); JobScheduler API Timing Constraint
  38. 38. JobInfo uploadJob = new JobInfo.Buildr(mSomeInt, mServiceComponent) .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) .setOverrideDeadline(DateUtils.HOUR_IN_MILLIS) .setRequiresCharging(true) .build(); JobScheduler API Extra Constraint
  39. 39. SyncAdapters Pre L Batching
  40. 40. SyncAdapters Pre L Batching GcmNetworkManager
  41. 41. // Schedule a task to occur between five and fifteen minutes from now: OneoffTask myTask = new OneoffTask.Builder() .setService(MyGcmTaskService.class) .setExecutionWindow( 5 * DateUtil.MINUTE_IN_SECONDS, 15 * DateUtil.MINUTE_IN_SECONDS) .setTag("test-upload") .build(); GcmNetworkManager.get(this).schedule(myTask); GcmNetworkManager GcmNetworkManager https://goo.gl/hTwIEt
  42. 42. // Implement service logic to be notified when the task elapses: MyUploadService extends GcmTaskService { @Override public int onRunTask(TaskParams params) { // Do some upload work. return GcmNetworkManager.RESULT_SUCCESS; } } GcmNetworkManager GcmNetworkManager https://goo.gl/hTwIEt
  43. 43. // Implement service logic to be notified when the task elapses: MyUploadService extends GcmTaskService { @Override public int onRunTask(TaskParams params) { // Do some upload work. return GcmNetworkManager.RESULT_SUCCESS; } } GcmNetworkManager adb shell am broadcast -a "com.google.android.gms.gcm.ACTION_TRIGGER_TASK" -e component -e tag GcmNetworkManager https://goo.gl/hTwIEt
  44. 44. Network Technique: Prefetching
  45. 45. 10 seconds 6 seconds
  46. 46. Fetch1MB Fetch1MB Fetch1MB Fetch1MB Fetch4MB PRE FETCHING! wait wait wait wait wait
  47. 47. @ Startup
  48. 48. How much do we prefetch? Quality pre-fetch is : about 1-5mb of data. about 1-2 minutes of data need
  49. 49. 2G = fetch 3 new photos
  50. 50. 4G = fetch 12 new photos
  51. 51. Network Problem: Payload Size
  52. 52. 45k quality : 70 164k quality : 100
  53. 53. Site JPG Quality Google Images Thumbnails 74-76 Facebook full-size images 85 Yahoo frontpage JPEGs 69-91 Youtube frontpage JPEGs 70-82 Wikipedia images 80 Windows live background 82 Twitter user JPEG images 30-100
  54. 54. READ goo.gl/skf1gp
  55. 55. JSON IS HORRIBLE
  56. 56. { "id": 1, "jsonrpc": "2.0", "total": 1, "max_id":276372795494133760, "result": [ { "id": 0, "guid": "2084d344-81fe-4714-9e2a-42c83b46083b", "isActive": true, "balance": "$1,507.00", "picture": "http://placehold.it/32x32", "age": 24, "latitude": -85.791587, "longitude": -64.615557, "tags": [ "quis", "est", "ea", "velit", "exercitation", "quis", "veniam" ], "friends": [ { "id": 0, "name": "Sanford Patton" }, Spaces, quotes, returns, names, are all verbose data.
  57. 57. { "id": 1, "jsonrpc": "2.0", "total": 1, "max_id":276372795494133760, "result": [ { "id": 0, "guid": "2084d344-81fe-4714-9e2a-42c83b46083b", "isActive": true, "balance": "$1,507.00", "picture": "http://placehold.it/32x32", "age": 24, "latitude": -85.791587, "longitude": -64.615557, "tags": [ "quis", "est", "ea", "velit", "exercitation", "quis", "veniam" ], "friends": [ { "id": 0, "name": "Sanford Patton" }, Copied into memory, must determine if string, int, date, etc.
  58. 58. FlatBuffers
  59. 59. FlatBuffers Scheme Compiler .java .cpp .go FlatBuffers http://goo.gl/r9xTXK
  60. 60. Smaller data wins the Internet. #PERFMATTERS TIP #9
  61. 61. Memory Performance WHY IS EVERYTHING SLOW????? I FORGET……...
  62. 62. GC Event! Allocatedmemory Memory Threshold
  63. 63. Fib3(..) GC Fib3(..)Main function FIB3 fcn haulted FIB3 fcn Resume
  64. 64. 16ms DRAW!DRAW! DRAW! 16ms 16ms UPDATE GC
  65. 65. GC events eat kittens framerate MEMORY Golden Rule
  66. 66. Memory Problem: Bitmaps
  67. 67. HEAP IMGIMG GC IMGIMG HEAP
  68. 68. Smaller Pixel Formats Down-Scale ImagesBitmap Re-use
  69. 69. Glide goo.gl/flNbyf Picasso goo.gl/tpTc1
  70. 70. Bitmaps are big Make them smaller #PERFMATTERS TIP #44
  71. 71. Memory Problem: HashMap
  72. 72. KEY Hash-to-index Allocated, but unused Allocated, but unused Stored Value
  73. 73. ArrayMap.java goo.gl/SCeQEL ArrayMap HASH #1 HASH #2 HASH #3 Hashes of keys sorted VALUE 2 KEY 3 VALUE 3 KEY 1 VALUE 1 KEY 2 Interwoven key / value
  74. 74. ArrayMap.java goo.gl/SCeQEL HASH #8 HASH #9 HASH #10 KEY HASH #5 HASH #6 HASH #7 HASH #1 VALUE 7 KEY 8 VALUE 8 KEY 1 VALUE 1 KEY 7 Key Index = (hashIndex *2) + 1 binary search HASH #7
  75. 75. collision search VALUE 7 KEY 8 VALUE 8 KEY 1 VALUE 1 KEY 7 Key Index = (hashIndex *2) + 1 HASH #8 HASH #9 HASH #10 KEY HASH #5 HASH #6 HASH #7 HASH #1 binary search
  76. 76. Empty But array still allocated Empty nothing allocated HashMap ArrayMap
  77. 77. <1000 objects Maps containing maps
  78. 78. Use ArrayMap in the right places. #PERFMATTERS TIP #76
  79. 79. Memory Problem: Auto Boxing
  80. 80. Primitive sizes boolean 8 bits int float 32 bits 32 bits boolean java.lang.Boolean int float java.lang.Float java.lang.Integer
  81. 81. Integer value = 0 Primitive int Integer Object Autoboxing
  82. 82. // Primitive version int total = 0; for (int i = 0; i < 100; i++) total += i; // Generic version Integer total = 0; for (int i = 0; i < 100; i++) total += i;
  83. 83. // Primitive version int total = 0; for (int i = 0; i < 100; i++) total += i; // Generic version Integer total = 0; for (int i = 0; i < 100; i++) //total += i; Allocates 83 new objects! (yea, i know, it’s confusing..) Allocates 0 new objects! // create new Integer(), // push in new value // add to total
  84. 84. HashMap <Primitive,Object> put update get autoboxing autoboxing autoboxing
  85. 85. HashMap <obj, obj> SparseBoolMap <bool,obj> SparseIntMap <int,obj> SparseLongMap <long,obj> LongSparseMap <long,obj> NoAutoboxing
  86. 86. LotsofGenerics Single Call Site AllocationTracker Memory Profiling 101 goo.gl/h1Cl9k
  87. 87. TraceView
  88. 88. Avoid Autoboxing #PERFMATTERS TIP #21
  89. 89. Memory Problem: ENUMs
  90. 90. 2556 Bytes
  91. 91. public static final int VALUE1 = 1; public static final int VALUE2 = 2; public static final int VALUE3 = 3; int func(int value) { switch (value) { case VALUE1: return -1; case VALUE2: return -2; case VALUE3: return -3; } return 0; } Bytes 2680 +124 bytes
  92. 92. public static enum Value { VALUE1, VALUE2, VALUE3 } int func(Value value) { switch (value) { case VALUE1: return -1; case VALUE2: return -2; case VALUE3: return -3; } return 0; } Bytes 4188 13x more than int version
  93. 93. public static enum Value { VALUE1, VALUE2, VALUE3 } 12-16 bytes for the array 20+ bytes (each)
  94. 94. If you’re using ENUMS STOP. #PERFMATTERS TIP #73
  95. 95. QUIT BEING STUPID. #PerfMatters Golden Rule

×