Android compiler D8, R8 에 대해 알아본다.
D8 : https://developer.android.com/studio/command-line/d8?hl=ko
R8 : https://developer.android.com/studio/build/shrink-code?hl=ko
Desugaring 은 일상에서 쓰이는 [식료품이나 식품합성을 목적으로 하는 재료에서 당성분을 제거하는 것] 을 의미하는 사전적 정의와 달리, 프로그래밍 언어에서는 [새로운 기능을 기존의 기능의 조합으로 구현하는 방식] 을 말합니다.
Legacy Android compiler 에서 [Java8 lamdbas] 코드를 dx 를 이용해 실행시키면, 아래와 같이 minimum API 26 에러가 발생했습니다.
API 26 미만에서도 [Java8 lamdbas] 를 실행하기 위해 Desugaring 을 지원하고 있습니다.
참고로 아래와 같이, Lamdbas 이외에도 여러 Desugaring 을 지원하고 있다.
- Sequential streams (java.util.stream)
- A subset of java.time
- java.util.function
- Recent additions to java.util.{Map,Collection,Comparator}
- Optionals (java.util.Optional, java.util.OptionalInt and java.util.OptionalDouble) and some other new classes useful with the above APIs
- Some additions to java.util.concurrent.atomic (new methods on AtomicInteger, AtomicLong and AtomicReference)
- ConcurrentHashMap (with bug fixes for Android 5.0)
기존 Desugaring 변환 과정을 제거하고, class2dex 편집의 일부로 만들어 더 빌드 시간을 줄였습니다.
뿐만 아니라 .dex 파일의 크기도 줄였습니다.
D8 = Dope*8 의 줄임말
Dope : 마약이라는 사전적 의미로, 비속어로 "대박이다", "쩐다" 의 의미로 쓰인다.
누군가 이를 제안을 했을 때, "Sounds dope (대박인데)" 라는 말이 나왔고 나머지 7명이 중얼거리면서 고개를 끄덕임.
이를 보고 노트에 "Dope*8" 이라 적고 이를 줄여서 "D8" 이라고 함.
R8은 D8와 다른 Tool 이나 Codebase 가 아닌, D8 을 개선한 버전입니다.
여기서 말하는 개선은 빌드 시간 줄이기 뿐만 아니라, Proguard 가 하던 코드 축소, 난독화를 R8 를 통해 개선 및 최적화를 통해 dex/apk 파일 크기도 줄인것을 말합니다.
최적화의 한 가지 사례를 살펴보면, Kotlin enum 을 when문과 함께 쓰는 코드를 Decompile 하면 아래와 같이 변환 됩니다.
새로운 [Naver$WhenMappings] class 를 만들고, 배열을 만들어서 구현한다.
만약 여러 곳에서 enum 과 when 문을 쓴다면, 계속해서 class 와 배열을 만들고 이는 미세하게나마 성능을 저하시킨다.
R8 은 이를 최적화하여 아래와 같이 변환합니다.
https://jakewharton.com/androids-java-8-support/
https://android-developers.googleblog.com/2017/08/next-generation-dex-compiler-now-in.html
https://android-developers.googleblog.com/2018/11/r8-new-code-shrinker-from-google-is.html