Android 놓치기 쉬운 안드로이드 성능 향상 팁 |
출처 : http://developer.android.com/training/articles/perf-tips.html
아래 두가지 규칙이 모든 성능 향상의 기본 법칙이다.
1. 필요 없는 일은 하지 말아라.
2. 피할 수 있다면 memory 를 잡는 일을 하지 말아라.
참고로 micro-optimization 을 한다고 해도 모든 단말에서 똑같은 성능향상이 있는 것이 아니다.
VM 의 종류, Processor 의 종류에 따라서도 조금씩 다르고, JIT 의 유무에 따라서도 다르다.
아래 항목들은 대부분의 환경에서 최적화시킬 수 있는 micro-optimization 기술을 소개한다.
쓸 데 없이 객체를 생성하지 말자.
GC 를 유발하며, GC 는 concurrent gc 가 진저브레드부터 도입되어 hiccups 현상은 완화되었지만,
그래도 전체적 성능하향으로 버벅대는 효과를 가져온다.
new String 같은 것도 피하고, Integer 대신 int 를 사용하며, multidimension array 보다는 single array 로 multidimension 을 커버하는 것이 좋다.
잠깐만 사용되는 임시 오브젝트는 가능하면 생성하지 않는 것이 좋다.
Virtual 보다는 Static
어떤 함수가 class 의 field 를 접근하지 않는다면 static method 로 바꾸자.
이 경우 invocation 할 때 15~20% 더 빠르게 작동한다.
Constants 에는 static final 을 부여하자.
field 들이 final static 으로 정의되어 있으면 class 를 초기화할 때 clinit 함수를 통하지 않아도 된다.
이들은 이미 dex file 의 static field initializer 에 포함되어 있다.
참고로 primitive type 과 String type 의 constants 외에는 static final 로 부여한다고 해도 성능향상은 없다.
하지만 상수에 final static 을 붙이는 것은 여전히 좋은 습관이다.
Avoid Internal Getter / Setter
일반 환경에서는 internal getter, setter 를 사용해도 큰 지장이 없지만,
Android 와 같은 mobile 환경에서는 잦은 getter, setter 호출 역시 expensive 하게 여겨질 수 있다.
JIT 이 없는 환경에서는 3배정도 성능향상이 있고,
JIT 이 있는 환경에서는 7배정도 성능향상이 있다.
proguard 를 사용하는 경우에는 inline accessor 를 제공하기 때문에 어떤 것을 사용해도 괜찮다..
Enhanced For Loop 를 사용하자.
Enhanced For Loop 라 하면 for-each loop 를 이야기한다.
for-each 는 Iterable interface 를 구현한 collection 혹은 array 에 대해 사용할 수 있다.
ArrayList 의 경우는 for-each loop 를 쓰지 않은 것이 약 3배 정도 빠르다!!!!!
하지만 그 외의 collection 의 경우에는 iterator 를 사용하는 것과 for-each 를 사용하는 것이 더 좋다.
loop 를 사용할 때는 length 부분을 local variable 로 만들어 사용하고,
collection 혹은 array 를 localize 해서 사용해야 더 좋다.
하지만 가능하면 for-each 를 사용하는 것이 가장 빠르다.
JIT 이 없는 환경에서는 for-each 가 더 빠르지만, JIT 이 있는 환경에서는 최적화된 일반 for 와 성능이 비슷하다.
결론적으로 일반적으로는 for-each 를 사용하는 것이 가장 좋고, ArrayList 에 대해서만 일반 for 문을 사용하는 것이 좋다.
Private inner class 에서 Outer class 의 variable 을 접근하는 경우 private 보다는 package accessor 를 사용하자.
public class Foo {
private class Inner {
void stuff() {
Foo.this.doStuff(Foo.this.mValue);
}
}
private int mValue;
public void run() {
Inner in = new Inner();
mValue = 27;
in.stuff();
}
private void doStuff(int value) {
System.out.println("Value is " + value);
}
}
사실 자바 언어에서는 위와 같은 inner class 에서의 outer class 의 private variable 의 접속을 문법적으로는 허락하지만,
VM 에서도 그런 것은 아니다. VM 에서는 static method 를 생성해서 접속하도록 한다.
/*package*/ static int Foo.access$100(Foo foo) {
return foo.mValue;
}
/*package*/ static void Foo.access$200(Foo foo, int value) {
foo.doStuff(value);
}
이는 성능저하가 나타날 수 있기 때문에 private field 를 package accessor 로 만드는 것이 좋다.
단 이럴 경우 외부에서 바로 접근할 수 있기 때문에 좋지 않다는 단점이 있기에, public API 같은 데서는 피해야 한다.
Floating-Point 사용하지 않기.
floating point 는 integer 에 비해 안드로이드 단말에서 약 2배정도 느리다.
desktop 에서는 double 과 float 의 차이가 거의 없기 때문에 double 을 쓰는 것이 좋다.
Library 를 잘 알고 사용하자.
System library 의 경우는 성능을 위해 aseembly 로 작성된 것도 있고, inline 처리를 하기도 해서 성능이 좋다.
JIT 가 생성한 같은 기능의 JAVA 코드보다 대부분 속도가 빠르다.
String.indexOf() 가 한 예고, System.arraycopy() 는 똑같은 로직을 하는 최적화된 코드로 작성했을 때에 비해 9배 빠르다.
Native Method 는 조심해서 사용하자.
NDK 를 사용해서 개발하는 것이 무조건 항상 효율적인 것이 아니다.
Java-native transition cost 가 그 대표적 이유이다.
게다가 native heap 에 memory allocation 을 하면 이를 해제하는 것이 pure java 만큼 쉽지 않다.
그리고 native code 가 architecture ( CPU, VM 등 ) 에 dependent 하기 때문에 호환성 문제도 생긴다.
native code 는 기존의 native codebase 가 있을 때 사용하는 것이 좋고,
그저 코드 일부분을 speed up 하기 위해 사용하는 것은 권장되지 않는다.
성능에 대한 미신.
JIT 이 없는 device 에서는 정확한 type 으로 method call 하는 것이 더 효과적이다.
예를 들면 HashMap map 을 param 으로 가지고 있는 함수보다 Map map 을 param 으로 가지고 있는 함수가 2배정도 느리다고 알져 있다.
하지만 실제로는 6% 정도만 느리다고 한다.
그리고 JIT 가 있는 경우에는 둘의 차이가 크지 않다.
JIT 가 없는 경우에는 local field access 가 global field access 보다 20% 더 빠르다.
하지만 JIT 환경에서는 거의 비슷하다.
항상 측정하라.
Optimization 을 하기 전에 해결하고 싶은 문제를 확실히 구체화시켜라.
현재 성능을 측정하고, 최적화 후의 성능을 또 측정하라.
TraceView 도 profiling 에 좋다.
하지만 traceview 를 사용할 때는 JIT 가 disable 된다.
그래서 traceview 가 도는 동안에는 속도가 좀 저하된다.
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] Launch UX Improvement. (0) | 2014.04.04 |
---|---|
[android] ThumbnailUtils 요런 녀석 있는 줄 알았삼? (0) | 2014.04.04 |
[android] video recording duration limit setting. (0) | 2014.04.03 |
[android] bitmap recycle 사용시 주의사항. (0) | 2014.04.02 |
[android] make screen awake, no sleep (2) | 2014.04.01 |
댓글