[Android] Enum의 사용에 대해 (DEX파일 크기 비교)

원문 링크 : http://androidjavapoint.blogspot.kr/2017/03/android-performance-avoid-using-enum-on.html

Android Performance: Avoid using ENUM on Android라는 글을 보면서부터 알게된 점이 있다.
Enum의 사용이 성능에 문제가 될 수 있다는 점. (자세한 내용은 위의 본문을 확인)


Enum의 문제점이라고 나열된 내용은 아래와 같다.

- Enum을 추가하면 dex파일의 크기가 커질 수 있다. 
  (Enum이 int 대비 13배정도 크다.)
- 앱이 실행될 때, dex파일이 Application Heap Memory에 Load 되므로
  dex파일의 크기가 커지는 것은 Memory이슈로도 연결된다.
  (이미지 출처 : The price of ENUMs (100 Days of Google Dev) )



그래서 dex파일에 얼마나 많은 영향을 주는지 직접 확인해봤다.

1. 기본 Enum의 구조
  Android Developer Page에서 확인 할 수 있는 enum의 구조는 아래와 같다.
  
  Enum은 기본 Object를 상속받아서 Comparable, Serializable을 implement하고 있다.
  (이러니 int 대비 13배가 클 수 밖에...)



2. Enum -> @IntDef, @StringDef 로 변경 시 Dex파일 크기 변경
  작업중이었던 실제 Project를 대상으로 Enum을 @IntDef와 @StringDef로 변경을 해보았다.
  7개의 Enum을 변경하였고 @IntDef로 변경한 것은 2개 나머지는 @StringDef로 변경하였다.
  (총 27개의 Enum instance를 변경함)
  (@IntDef와 @StringDef의 사용은 최 상단의 원문에서 확인할 수 있다.)

  변경 전 dex의 크기 : 9,379,488 byte
  변경 후 dex의 크기 : 9,373,628 byte 
  7개의 Enum(총 27개 Instance) 변경시 약 6,000byte 정도 줄어드는 것을 확인 할 수 있었다.
  
  좀 더 명확한 확인을 위해 1개의 Enum을 각각 String과 int로 변경해봤다.
  기본 Enum 1개 있을 때 : 9,374,212 byte
  String으로 변경 시 : 9,373,656 byte  (약 600byte 감소)
  int로 변경 시 : 9,373,656 byte  (약 600byte 감소)
  String과 int가 같다니... 이상하긴 하지만 일단 결과는 이렇다...


3. Enum -> Object로 변경시 Dex파일 크기 변경
   작업중이었던 프로젝트에서 사정이 있어서 (좋은 방법은 아니었을지 모르지만)
   아래와 같은 방식으로 작성했던 코드가 있었다. 

  혹시 이 녀석을 일반 Class로 변경해서 만든다면 어떻게 될까? 라는 의문에
  아래와 같이 코드를 변경해서 dex파일 크기를 비교해봤다.     
   
   비교 결과는 다음과 같다. 
   변경 전 : 9,373,628 byte 
   변경 후 : 9,373,276 byte
   약 350byte 차이.. 




결론
  대부분의 경우에 enum보다는 다른 방법을 쓰는 것이 약간의 이익을 얻을 수 있다고 확인했다.
  지금은 단순히 7개의 Enum class에서 6,000byte 수준의 이득은 정말 작은 것 일수 있지만,
  Colt McAnlis 아저씨도 말했듯, 
프로젝트의 규모가 점점 더 커지게 되고, 
  Enum의 사용이 많아지면 잃게되는 부분도 더 많기 때문에
  Enum 대신 
@IntDef @StringDef 등을 사용하는 습관이 
성능을 좋게 하는 습관이라 생각된다. 

댓글

이 블로그의 인기 게시물

[Android] DataBinding의 동작방식 - 4. include Tag 혹은 ViewStub 사용시의 Binding

[Android] DataBinding의 동작방식 - 5. Listener, Callback (CustomView의 Callback을 람다식으로 Binding하기)

[Android] DataBinding의 동작방식 - 2. BindingAdapter의 기본 및 사용 시점