Designing for Performance (성능의 최적화)

2010. 2. 3. 21:11OS/Android

직접 영어를 해석하는 것이 가장 좋을듯 싶다.

Android를 하는데 있어서, 성능을 고려하는 Tip 이니, 숙지하는 것이 좋을 것 같아서, 정리를 해봤습니다.

"아무리 일반 휴대폰 보다 좋다 한들, 보통 데스크탑 컴퓨터보다 좋을리가 없고, 파워가 남아 돌지 않기에, 최대한 효율적인 코드 작성이 필요하다"

리소스가 제약된 시스템에 대해서는 두가지 룰이 있는데,
첫째, 할 필요가 없는 것은 하지 말고 , 둘째 피할 수 있다면, 메모리 할당하지 마라.

임베디드 디바이스에서, 마이크로 최적화가 가끔 효율적인 데이터 구조나 알고리즘을 개발하는 것을 더 어렵게 만드는 것은 사실이다. 기존 프로그램(데스크탑용)을 안드로이드에 가져온다면, 문제가 된다는 이야기다.!!!
애플리케이션이 같은 디바이스에서 실행 될 것이기 때문에, 우리는 모두 이렇게 함께 하나의 길에 있다.
이 문서를 여러분이 자동차 면허증을 얻었을때 배워야 하는 도로의 규칙들 같이 생각하면 될것이다.
여러분의 코드를 충분히 빠르게 만들어라.




1. Avoid Creating Objects
 : 객체를 생성하는 것을 피하라!


2. Use Native Methods
 : Native 메소드를 사용하세요


3. Prefer Virtual Over Interface
  : Virtual 이 좋다!! Interface 보다... 아래꺼를 사용해라~
Map myMap1 = new HashMap(); 
HashMap myMap2 = new HashMap();

4.Prefer Static Over Virtual
  : Static 이 좋다!! Virtual 보다...

5.Avoid Internal Getters/Setters
 : 내부적인 Getter / Setter 를 피하시죠 , 바로 사용하시라는 (비경제적이라고 강조하네요)
 i = getCount();
 i = mCount();


6.Cache Field Lookups
 : 지역변수 가 필드를 사용하는 것보다 훨~ 빠르다고 하니, 변경해주시길 바랍니다.

for (int i = 0; i < this.mCount; i++) 
      dumpItem
(this.mItems[i]);

  int count = this.mCount; 
 
Item[] items = this.mItems; 
  
 
for (int i = 0; i < count; i++) 
      dumpItems
(items[i]);

이거 나쁜 예제 이죠~ this.getCount() 는 아니되어요!!!
for (int i = 0; i < this.getCount(); i++) 
    dumpItems
(this.getItem(i));

아래와 같은 예제와 같이 별도 지역변수로 변경해서 사용해주시길 바랍니다.
   protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) { 
       
if (isHorizontalScrollBarEnabled()) { 
           
int size = mScrollBar.getSize(false); 
           
if (size <= 0) { 
                size
= mScrollBarSize; 
           
} 
           
mScrollBar.setBounds(0, height - size, width, height); 
           
mScrollBar.setParams( 
                    computeHorizontalScrollRange
(),                     computeHorizontalScrollOffset(), 
                    computeHorizontalScrollExtent
(), false); 
           
mScrollBar.draw(canvas); 
       
} 
   
}

7. clare Constants Final
 : 간단하다, Constants(상수,등등)는 final로 지정해라!


static int intVal = 42; 
static String strVal = "Hello, world!";

static final int intVal = 42; 
static final String strVal = "Hello, world!";


8. Use Enhanced For Loop Syntax With Caution
: 아래 주의 사항을 잘 읽어봐라!

public class Foo { 
   
int mSplat; 
   
static Foo mArray[] = new Foo[27];     
   
public static void zero() { 
       
int sum = 0; 
       
for (int i = 0; i < mArray.length; i++) { 
            sum
+= mArray[i].mSplat; 
       
} 
   
} //retrieves the static field twice and gets the array length once for every iteration through the loop. (컨테이너 종류에 따라 성능 저하 발생 우려, ArrayList 사용 자제)
 
   
public static void one() { 
       
int sum = 0; 
       
Foo[] localArray = mArray; 
       
int len = localArray.length; 
 
       
for (int i = 0; i < len; i++) { 
            sum
+= localArray[i].mSplat; 
       
} 
   
}  // pulls everything out into local variables, avoiding the lookups.
 
   
public static void two() { 
       
int sum = 0; 
       
for (Foo a: mArray) { 
            sum
+= a.mSplat; 
       
} 
   
} // Enhanced For Loop 는 사용을 자제하라 
}


9. Avoid Enums
 : 외부 공개 API가 아닌 이상 Enums 의 사용을 자제 하세요

public class Foo { 
   
public enum Shrubbery { GROUND, CRAWLING, HANGING } 
}

Shrubbery shrub = Shrubbery.GROUND;

for (int n = 0; n < list.size(); n++) {     
     
if (list.items[n].e == MyEnum.VAL_X) 
       
// do stuff 1 
   
else if (list.items[n].e == MyEnum.VAL_Y) 
       
// do stuff 2 
}

   int valX = MyEnum.VAL_X.ordinal(); 
   
int valY = MyEnum.VAL_Y.ordinal(); 
   
int count = list.size(); 
   
MyItem items = list.items(); 
 
   
for (int  n = 0; n < count; n++) 
   
{ 
       
int  valItem = items[n].e.ordinal(); 
 
       
if (valItem == valX) 
         
// do stuff 1 
       
else if (valItem == valY) 
         
// do stuff 2 
   
}



10. Use Package Scope with Inner Classes
:  내부 클래스에 Package Scope를 사용하라

public class Foo { 
   
private int mValue;     
    p
ublic void run() { 
       
Inner in = new Inner(); 
        mValue
= 27; 
       
in.stuff(); 
   
} 
 
   
private void doStuff(int value) { 
       
System.out.println("Value is " + value); 
   
} 
 
   
private class Inner { 
       
void stuff() { 
           
Foo.this.doStuff(Foo.this.mValue); 
       
} 
   
} 
}


/*package*/
static int Foo.access$100(Foo foo) { 
   
return foo.mValue; 
} 
/*package*/
static void Foo.access$200(Foo foo, int value) { 
    foo
.doStuff(value); 
}




11.Avoid Float
 : float , double 등의 실수 자료형 는 사용을 피하라!



12 . Some Sample Performance Numbers

Action Time
Add a local variable 1
Add a member variable 4
Call String.length() 5
Call empty static native method 5
Call empty static method 12
Call empty virtual method 12.5
Call empty interface method 15
Call Iterator:next() on a HashMap 165
Call put() on a HashMap 600
Inflate 1 View from XML 22,000
Inflate 1 LinearLayout containing 1 TextView 25,000
Inflate 1 LinearLayout containing 6 View objects 100,000
Inflate 1 LinearLayout containing 6 TextView objects 135,000
Launch an empty activity 3,000,000


오늘도 여기까지 입니다.
위 사항은 이후 더 공부해서, 개선 보완할수 있는 부분에 대해서는 추가 하도록 하겠습니다.

'OS > Android' 카테고리의 다른 글

Hello Android!! 튜토리얼 따라하기!! 1탄  (0) 2010.02.02
안드로이드 개발 환경 설정  (1) 2010.02.02