2019. 9. 21. 22:58ㆍAndroid
구글에서 권장하는 성능 개선 방법
#2가지 기본 규칙
-
불필요한 것은 하지 않기
-
가능하다면 메모리 할당하지 않기
1. 불필요한 Object 생성 피하기
가능한 한 단기 임시 객체를 만들지 않는 것이 좋다. 생성되는 객체가 적을수록 사용자 환경에 직접적인 영향을 미치는 가비지 컬렉션의 빈도가 낮아진다.
2. 적절한 Static 사용하기
개체의 필드에 접근할 필요가 없는 경우, 매소드를 static으로 만드는 것을 권장한다. 그러면 호출이 약 15~20% 빨라진다고 한다.
3. 상수에는 static final 사용하기
4. 향상된 for 루프(for-each) 사용하기
아래의 예에서 기본 for 문과 for-each 문의 차이를 보자.
속도는
zero() < one() <= two() 이다.
단, 여기서 two() 가 one()보다 속도가 빠르거나 같은 이유는 , JIT가 없는 기기에서만 one() 보다 빠른 속도를 갖는다.
*JIT : just-in-time compilation 뜻으로, 프로그램을 실행하는 시점에 기계어로 번역하는 컴파일러.
zero()가 가장 느릴 수 밖에 없는 이유는, 루프를 돌 때마다 array.length를 계산해야 하기 때문.
one() 과 zero()의 성능 차이는 one()에서는 배열의 길이 차이 뿐.
Foo[] array = ...
public void zero() {
int sum = 0;
for (int i = 0; i < array.length; ++i) {
sum += array[i].splat;
}
}
public void one() {
int sum = 0;
Foo[] localArray = array;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].splat;
}
}
public void two() {
int sum = 0;
for (Foo a : array) {
sum += a.splat;
}
}
5. private inner class의 private 액세스 사용 대신 패키지 고려하기
6. 부동 소수점 사용 피하기
보통 안드로이드 기기 내에서 부동 소수점(실수)는 정수보다 약 2배정도 느리다.
공간이 문제되지 않는다면, float 보다 공간측면에서 2배 더 큰 double 쓸 것을 권장
7. 라이브러리 사용하기
8. native method 사용은 신중하게
NDK를 사용하여 네이티브 코드로 앱을 개발하는 것이 자바 언어로 프로그래밍하는 것보다 반드시 효율적이지는 않습니다. 우선 자바 네이티브 전환과 관련된 비용이 있으며, JIT는 이러한 경계를 넘어 최적화를 수행할 수 없습니다. 네이티브 리소스(네이티브 힙, 파일 설명자 등에 대한 메모리)를 할당하는 경우, 이러한 리소스를 적시에 수집하도록 조정하는 것이 훨씬 더 어려울 수 있습니다. 또한 실행하고자 하는 각 아키텍처에 대해 코드를 컴파일해야 합니다(JIT로 이에 의존하기보다). 동일한 아키텍처로 간주하는 여러 버전을 컴파일해야 할 수도 있습니다. G1에서 ARM 프로세서용으로 컴파일된 네이티브 코드는 Nexus One에서 ARM을 최대한 활용할 수 없으며, Nexus One에서 ARM용으로 컴파일된 코드는 G1의 ARM에서 실행되지 않습니다.
네이티브 코드는 자바 언어로 작성된 Android 앱의 '속도 향상'이 아니라 Android로 이식하려는 기존의 네이티브 코드베이스를 가지고 있을 때 주로 유용합니다
9. 성능 개선을 하기 전에 먼저 앱의 문제점을 측정
그 외
10. Rendering 성능 높이기
오버드로(overdraw) 줄이기
*오버드로 란 , 말 그대로 화면이 그려질 때 과잉으로 그려진다는 의미다.
위의 이미지에서 1X , 2X 등의 의미는, 화면에 픽셀이 몇번이나 더 그려졌는지 이다.
즉,
1X : 화면에 픽셀이 1번 겹쳐 그려짐. 즉, 총 2번 그려졌다.
4X+ : 화면에 픽셀이 4번(이상)이나 겹쳐 그려짐. 즉, 총 5번(이상) 겹쳐 그려졌다.
1) xml 코드에서 불필요하게 backgroud가 중복되는걸 피하자.
예를 들어,
아래 코드를 보면, parent_view의 background와 child_view의 background 가 모두 black으로 중복 설정되어 있다.
이 경우, child_view에만 설정을 해도 무방한데 불필요하게 중복된 경우이다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/parent_view"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<LinearLayout
android:id="@+id/child_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/black">
</LinearLayout>
</LinearLayout>
2) xml 계층 구조를 단순화하자. View hierarchy 최적화
참고 https://developer.android.com/topic/performance/rendering/optimizing-view-hierarchies
디바이스에서 렌더링 체크
GPU 렌더링 속도 프로파일링
설정 -> 개발자 옵션 -> "모니터링" 섹션의 "프로필 GPU 렌더링" 선택
*참고 : 이 옵션은 NDK를 사용하는 앱에서는 작동안함.
오버드로
설정 -> 개발자 옵션 -> "하드웨어 가속 렌더링" 섹션의 "GPU 오버드로 디버깅" 선택
참조
https://developer.android.com/studio/profile/inspect-gpu-rendering?hl=ko
'Android' 카테고리의 다른 글
Fragment에 대하여 - (1/2) (0) | 2020.03.01 |
---|---|
[Android] DI(의존성 주입)과 Koin에 대하여 (0) | 2019.11.15 |
[Android]Android Architecture Pattern 에 대하여 - (2) MVVM (0) | 2019.10.08 |
[Android] Android Architecture Pattern 에 대하여 - (1) (0) | 2019.09.28 |
[Android] Paging Library 에 대하여 (0) | 2019.09.14 |