본 포스팅은 DroidKaigi 2016 パフォーマンスを追求したAndroidアプリを作るには 을 기본으로 번역하여 작성했습니다
제 일본어 실력으로 인하여 오역이나 오타가 발생할 수 있습니다.
실제 슬라이드의 일본어
부분을 번역했다는 점 양해바랍니다.
퍼포먼스를 요구하는 Android 어플을 만들기 위해서는
앙케트 : “퍼포먼스 향상”에 대한 인상
대상 : 수도권 체류 Android 개발자 (5인)
따분하고 귀찮고 수면에 잘 나타나지 않는 것
하지만, 개인적으로는 이것을 신경 쓸지 말지가 개발자로서의 가치를 크게 좌우한다 (그런 느낌이 든다)
…그러므로, 이야기하고 싶다
서론
dumpsys이 많은 부분
을 차지하고 있습니다퍼포먼스를 요구하는 Android 어플을 만들기 위해서 하는 것
프로그래밍 기술에 대해서는 Udacity에서 배우자
Study Jams 프로그램의 참가등록은 이쪽 https://events.withgoogle.com/studyjams-japan-2016/
Study Jams 프로그램의 참가 등록하고 Udacity의 코스에 등록하고, 전용 온라인 커뮤니티에 참가할 수 있습니다
퍼포먼스에 대한 개인적인 기본원칙
퍼포먼스의 지표나 요인은 매일 복잡화되고 있다.
다양한 관점에서의 다방면으로 생각한다
추측이나 개인적인 생각은 오류를 포함한다 (도시 전설)
설명할 수 없으면 고생한다
일상적으로 무리 없이 한다 (생각되는 것을 한다)
측정은 충전하지 않은 상태로
충전되고 있을 때는 디바이스의 동작이 바뀐다. 기본적으로 미충전 상태로 한다
실제로 충전하지 않는 것이 베스트. 안된다면 갱신정지상태를 사용해서 미충전상태를 만든다
dumpsys battery unplug 혹은 set usb 0
※ 사용이 끝나면 다시 복원할 것 (reset) 을 잊지 않도록
unplug의 오해
dumpsys battery unplug (혹은 set usb 0) 는 Doze 에서는 미충전 상태
가 된다.
하지만 배터리 상태 (BatteryManager)로서는 갱신정지상태
에 불과하다.
그래서, 미충전 상태로 만들고서 갱신정지
로 한다.
※ 다만 실제로는 충전되고 있으므로 현실의 미충전과는 엄밀하게 다르다
소비전력에 대해서
배터리의 여유와 마음의 여유
전력소비는 가장 중요한 퍼포먼스 지표
질문
Nexus5를 이용해
카메라의 플래시 라이트
를 하루 종일
사용 가능한 어플을 만들고 싶다
실현 가능한가?
그러면 반나절이라면? 6시간은?
Nexus5의 경우
플래시 라이트의 소비전류 대략 540 mA
배터리 방전용량 2300 mAh
이론상 4시간
정도 (2300 / 540 ≒ 4.2)
당연하지만, 실제로는 다른 어플이나 다른 기기의 소비전력에 의존하므로 더욱 줄어듭니다.
전류소비량을 알기 위해서는
리소스들의 정의
를 하는 시스템 apk소비전력량
을 정의한 XML 파일<?xml version="1.0" encoding="utf-8"?>
<device name="Android">
<item name="none">0</item>
<item name="screen.on">82.75</item>
<item name="screen.full">201.16</item>
<item name="camera.avg">804.85</item>
<item name="camera.flashlight">546.37</item>
<item name="bluetooth.active">51.55</item>
<item name="bluetooth.on">0.79</item>
<item name="wifi.on">3.5</item>
<item name="wifi.active">73.24</item>
<item name="wifi.scan">75.48</item>
...
<item name="gps.on">76.23</item>
<item name="radio.active">185.19</item>
<item name="radio.scanning">99.2</item>
<array name="radio.on">
<value>4.8</value>
<value>1.11</value>
</array>
<array name="cpu.speeds">
...
</array>
<item name="battery.capacity">2300</item>
...
</device>
※ 단위는 mA
소비전력 기준을 파악 · 이해
최근 하드웨어 기능
NFC | 라디오 | 라이트 | 심장박동 |
자이로 | 전화 | 배터리 온도 | 조도 |
가속도 | 카메라 | 마이크 | 기온 |
Bluetooth | GPS | 터치패널 | 습도 |
Wifi | 자기 | 지문 | 기압 |
dumpsys batterystats
배터리의 다양한 정보를 보는 것이 가능해 매우 편리
매일 봐도 질리지 않는 레벨
dumpsys batterystats –charged
35초
11초
정도보는 건 귀찮다
Battery Historian
Battery Historian
# 다운로드
$ go get -u github.com/google/battery-historian/...
$ cd $GOPATH/src/github.com/google/battery-historian
# 컴파일
$ bash setup.sh
# 서버 기동 디폴트는 포트 9999
$ go run cmd/battery-historian/battery-historian.go
# 총계정보취득
$ adb bugreport > hoge.txt
http://localhost:9999에 접근해서 얻은 총계정보 (hoge.txt)를 업로드하면 볼 수 있다
Background에서의 소비
Android의 특징으로서 소비전력의 5~7할
은 IDLE시에 소비되는 경향 (라고 한다)
Background에서의 소비를 줄이는 것이 중요
JobScheduler
JobInfo uploadTask = new JobInfo.Builder(mJobId, mServiceComponent)
.setRequiredNetworkCapabilities(JobInfo.NETWORK_TYPE_UNMETERED)
.build();
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(uploadTask);
GCM Network Manager
mGcmNetworkManager = GcmNetworkManager.getInstance(this);
OneoffTask task = new OneoffTask.Builder()
.setService(MyTaskService.class)
.setTag(TASK_TAG_WIFI)
.setExecutionWindow(0L, 3600L)
.setRequiredNetwork(Task.NETWORK_TYPE_UNMETERED)
.build();
mGcmNetworkManager.schedule(task);
Doze Framework
http://developer.android.com/intl/ja/training/monitoring-device-state/doze-standby.html
Doze에 대해서는 中西良明(@chun_ryo)님의 어제 발표자료가 알기 쉬우므로 그것을 권장합니다! Android의 저전력에 대한 생각 https://goo.gl/yxBYOH
Doze의 상태 개요
ACTIVE –화면을 끈다–> INACTIVE –일정 시간 경과 (30분)–> IDLE_PENDING –일정 시간 경과 (30분)–> IDLE (※ IDLE중에는 여러가지가 중지된다) –일정 시간 경과 (점점 길어진다, 1시간, 2시간 … 6시간)–> IDEL_MAINTENANCE (※ 처리가능한 영역) –화면을 켠다 …등–> ACTIVE
상태 확인
$ dumpsys deviceidle
강제상태 변경
$ dumpsys deviceidle step
Doze에 대해서는 中西良明(@chun_ryo)님의 어제 발표자료가 알기 쉬우므로 그것을 권장합니다! Android의 저전력에 대한 생각 https://goo.gl/yxBYOH
UI에 대해서
많은 퍼포먼스 지표는 UI에 귀결하여 나타나고 있다.
시간과 사용자의 반응 지표
250ms
이하를 유지하면 사용자는 빠르다고 느낄 수 있다
1초
이하를 유지하면 사용자는 집중력을 유지한다
지연시간 | 사용자 반응 |
---|---|
0 - 100ms | Instant |
100 - 300ms | Feel sluggish |
300ms - 1s | Machine is working… |
1s + | Mental context switch |
10s + | I’ll come back later… |
Breaking the 1000ms Time to glass Mobile Barrier : https://www.youtube.com/watch?v=Il4swGfTOSM
렌더링 역사
GingerBread이전 | CPU 사용 |
Honeycomb | 하드웨어 가속 추가 |
ICS | 하드웨어 가속이 디폴트 |
JellyBean | VSYNC로 프레임 최적화 |
이 부분은 대략 60fps로 그린다
Jank
최근 많은 디바이스에서는 60fps
로 그려진다고 생각할 수 있다
즉 16 - 17ms
마다 1회
렌더링이 맞추지 못하면, Jank
가 발생한다
Skipped 136 frames! The application may be doing too much work on its main thread.
Jank
가 발생하면 프레임이 Skip 된다
많은 경우, 애니메이션 생략이나 Jump라는 형태로 사용자에게 보인다
Jank
를 피하는 (줄이는) 것이 중요
View의 렌더링
3단계
Measure -> Layout -> Draw
Hierarchy Viewer로 가시화 가능
Nest에 의한 Remeasure
※ RelativeLayout이나 LinearLayout를 중첩하면 Measure가 여러 번 실행되는 것에 의해
예)
Nest한 상태 | 개선 후 |
---|---|
Measure: 33.3338ms | Measure: 0.548ms |
Layout: 2.810ms | Layout: 0.210ms |
Draw: 9.526ms | Draw: 2.0.46ms |
Overdraw 회피
Overdraw
를 의심하는 것이 좋다 (좋았다)
http://developer.android.com/intl/ja/tools/performance/debug-gpu-overdraw/index.html
GPU Profiling
16ms Border : 대략 이보다 아래에 맞추면 문제없다
색 | 설명 |
---|---|
Blue | View의 생성. View 개수나 onDraw 처리에 의존 |
Purple | 그리는 리소스 전송 |
Orange | GPU 처리를 CPU가 기다리는 시간 |
Green | VSYNC의 연기 |
Red | GPU의 그리기 실행 |
dumpsys gfxinfo
Jank
정보가 나오므로 추천dumpsys gfxinfo com.android.chrome
framestats
옵션을 적용함으로 CSV로 나온다
dumpsys gfxinfo com.android.chrome framestats
그 외 (통신, 메모리, 프로세서)
통신 최적화
본격적으로 다루기에는 상당히 어려운 인상
개인적으로 간단한 어프로치
로서는 …
AT&T ARO
매우 추천
이걸로 Green이 아닌 항목을 보면 되므로 간단
ARO 평가항목
다양한 통신의 통계 수집 · 가시화이나 통계와 대응한 조작 녹화도 가능
메모리 최적화
이것도 통신과 같게 본격적으로 다루는 것은 상당히 어렵다
개인적으로 간단한 어프로치
로서는 …
dumpsys meminfo
디자이스 전체의 메모리 사용량 Summary
dumpsys meminfo [pid]
지정한 프로세스 ID 메모리 사용량
dumpsys procstats [package]
지정한 어플의 최근 3시간, 최근 24시간의 메모리 사용량 총계 (스크린 On/Off시 등 복수 축으로)
Memory Leak 검출
Heap dump, Allocation Tracker, Memory Analyzer Tool (MAT) 등이 지름길
개인적인 추천은 LeakCanary
onTrimMemory
※ 저는 사용하지 않지만, 사용하고 있는 사람 있습니까?
CPU 최적화 (?)
라고 해도…
개인적으로는 어플 개발자로서는
대부분 ANR
이나 jank
를 막는 목적으로 어플의 프로세스나 스레드가 어느 정도 CPU를 이용하고 있는가를 파악해두면 좋다고 생각된다.
dumpsys cpuinfo
디바이스 전체의 CPU 사용량
※ 비슷한 것은 개발자용 옵션 -> CPU 사용량 표시로도 가능
Systrace
CPU 사용량을 가시화하는 지름길 도구
Jank도 알기 쉽다
http://developer.android.com/intl/ja/tools/debugging/systrace.html
Trepn Power Profiler
마지막으로
comments powered by Disqus
Subscribe to this blog via RSS.
LazyColumn/Row에서 동일한 Key를 사용하면 크래시가 발생하는 이유
Posted on 30 Nov 2024