-
Performance 에 대해서는 항상 measure 를 해봐야 한다.
* Kotlin
-
Kotlin app 은 더 size 가 크고 느릴 것이다.
-
단순한 밴치마킹용 심플 코드가 아닌, Google Drive 를 converting 해보았다.
16K lines / 171 Files / 41 Build Target
Startup time 은 동일 / 25% code line 줄어듬 / 2% 정도 compile code size 가 줄어듬
성능은 동일하지만, 유지보수해야 하는 코드가 줄어들었다는데 큰 의미가 있다.
* Code pattern
Fields Access Patterns (getter/setter)
getter/setter 는 expensive 할 것이다.
Jetpack benchmark lib 으로 측정했다. ( prewarm 도 진행해준다. )
no difference
ART team 에서 예상했던 데로다. ART 가 이런 access 를 compile 시 inline 시킨다.
그러므로 encapsulation 을 해치지 않는 get/set 을 쓰자.
Using Lambdas
Lambda 는 inner class 사용보다 느릴 것이다.
no difference
lambda, nested class, top level class 모두 동일하다.
lambda 가 anonymous inner class 로 변신하기 때문에 동일할 수밖에 없다.
그러므로 가독성 측면에서 이로우며, 추후 개선 여지가 있는 lambda 를 사용하자.
* Memory
안드로이드의 Memory allocation 은 느리다.
지속적으로 개선해서 빨라지고 있다.
L 에서는 Custom Allocator
O 에서는 Bump Pointer
O부터는 super fast 라고 부를 수 있을 정도이다.
Myth 로 인해 Pool 을 사용하는 방식이 많이 사용되었다. ( no allocation & no gc )
Pool 에서 put/retrieve 하는 과정에서 synchronize 를 보통 하게 되는데, 이와 allocation 을 비교하면 거의 비슷한 성능을 보인다.
Pool 이 장점을 가질 때가 있지만, Pool 은 foot print 측면에서 단점이 있다.
보관하는 object 의 size 가 클 경우는 성능상의 단점을 보이기도 한다.
그래서 꼭 필요한 경우가 아니라면, 이미 memory allocation 과 gc 는 출분히 빠르니 pool 대신 그냥 로직을 짜는 것이 조금 더 추천된다고 볼 수 있겠다.
물론 Pool 을 쓰지 말라는 것은 아니다. create 가 expensive 한 것은 pool 을 쓰는게 더 유용할 수 있다. 잘 보고 쓰자.
안드로이드의 GC 는 느리다.
GC 도 지속적으로 개선해서 빨라지고 있다.
GC 는 더 이상 Stop-the-World collection 을 사용하지 않는다.
jank 등은 최소화되었다.
Android 10 에서는 generational concurrent collection 이 더 빨라졌다.
Google Sheet 에서는 68% 정도의 개선이 있었다.
* Profiling
Debuggable app 을 profiling 하는 것은 괜찮다.
debuggable=true 일 때는 측정결과가 중구난방이었다.
그러나 동일한 것을 debuggable=false 로 두니 일관된 결과를 보였다.
또한 비교가 아닌 절대적 시간을 볼 때는 더 이슈가 되는데,
debuggable=true 와 false 의 view inflating 에서는 성능이 2배 차이가 났다.
그 이유는 runtime 에서 debuggable 일 때는 코드 최적화를 별로 하지 않는다.
그래서 production build 에서의 코드와는 한참 다를 것이다.
* Strange things
Multidex 가 성능에 영향이 있니? Dex file 이 클수록 영향이 있니?
계산기앱을 single dex 와 multi dex 로 나누었을 때
startup time 은 차이 없음.
Apk size 는 조금 늘어남.
메모리 사용도 조금 늘어남. ( 중복 data 를 가진다. cache, symbol table 등의 영향으로 )
Custom 으로 dex 를 split 할 떄는 main dex 에 뭐가 들어있느냐가 성능에 영향을 미칠 수 있다.
따라서 R8/D8 을 통해 가 알아서 하도록 두는게 최선이라고 본다.
니 생각보다 Dead code 가 많을 것이다.
ART profile 이 Android P 이상에서는 자주 쓰이는 함수들에 대해 profile 을 진행한다.
그리고 시스템은 이 profile 정보를 바탕으로 optimization 을 진행한다.
구글 코드를 봤을 때 앱의 14% 정도만 profile 되었다.
86% 는 거의 실행되지 않았다고 볼 수 있다.
많은 에러 핸들링, 호환성 코드 등이 있기 때문이다.
그리고 자주 사용되지 않는 기능들도 당연히 있을 것이다.
R8 을 사용해서 shrink 를 하라.
자주 사용하지 않는 코드를 제거하라. (apk 사이즈 줄이자)
* 직접 해봐라
-
Android Studio 가 profiler 를 가지고 있다.
Kotlin, Java, Native code 모두 가능하다.
-
Perfetto & Systrace
아주 자세한 정보를 보여준다.
-
Jetpack Benchmark lib
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[regex] 정규식의 성능을 개선해보자. (0) | 2020.02.27 |
---|---|
[android] Notification Channel ( Oreo 부터 생김 ) (0) | 2020.02.26 |
[android] AndroidX 로의 migration : 그 때가 왔다! ( from Dev Summit 19 ) (0) | 2019.11.15 |
[android] Coding in Style: Static Analysis with Custom Lint Rules ( from Dev Summit 19 ) (0) | 2019.11.14 |
[android] Pie (android 9) 의 변경점 (0) | 2019.07.31 |
댓글