Compose 컴파일러는 안정성을 어떻게 추론하고 타입을 결정할까?
Compose 컴파일러는 안정성을 어떻게 추론하고 타입을 결정할까?
Jetpack Compose는 스마트 리컴포지션(Smart Recomposition) 시스템을 활용하여 UI 업데이트를 최적화합니다. 이 최적화의 핵심에는 **안정성 추론(stability inference)**이 자리하고 있습니다. 안정성 추론이란, 특정 타입의 값이 시간이 지나도 변하지 않을 수 있는지를 컴파일러가 판단하는 능력을 의미합니다. Compose 컴파일러가 안정성을 어떻게 추론하는지 이해하면, 보다 높은 성능의 Compose 코드를 작성할 수 있습니다.
안정성 추론은 Compose가 리컴포지션을 건너뛸지 여부를 판단하는 근거가 되기 때문에, Compose 성능 최적화를 고민하는 개발자라면 반드시 이해해야 하는 개념입니다.
안정성(Stability)이란 무엇인가?
Compose에서 특정 타입이 **안정적(stable)**이라고 간주되려면, 다음 조건을 모두 충족해야 합니다.
- 동일한 두 인스턴스에 대해
equals()를 호출했을 때 항상 같은 결과를 반환해야 합니다. - 타입의 public 프로퍼티가 변경되면, 컴포지션(Composition)에 변경 사항이 통지되어야 합니다.
- 모든 public 프로퍼티 역시 안정적인 타입이어야 합니다.
대표적인 예시는 다음과 같습니다.
- 안정적(Stable): 원시 타입(
Int,String,Boolean),@Immutable로 선언된data class, 함수 타입 - 불안정(Unstable):
var프로퍼티를 가진 클래스, 가변 컬렉션(MutableList,MutableMap)
이처럼 안정성은 단순히 값이 변하지 않는다는 의미가 아니라, 값이 변경될 경우 반드시 Compose에 알릴 수 있는지 여부까지 포함하는 개념입니다.
안정성 타입 시스템
Compose 컴파일러는 컴파일 과정에서 안정성 정보를 추적하기 위해 정교한 타입 시스템을 사용합니다. 이 시스템은 Stability라는 sealed class로 표현됩니다.
sealed class Stability {
class Certain(val stable: Boolean) : Stability()
class Runtime(val declaration: IrClass) : Stability()
class Unknown(val declaration: IrClass) : Stability()
class Parameter(val parameter: IrTypeParameter) : Stability()
class Combined(val elements: List<Stability>) : Stability()
}
각 하위 클래스는 안정성에 대한 확신 수준을 나타냅니다. 아래에서 하나씩 자세히 살펴보겠습니다.
1. Certain Stability (확정적 안정성)
class Certain(val stable: Boolean) : Stability()
Certain은 컴파일 타임에 안정성 여부를 100% 확신할 수 있는 타입을 나타냅니다. 컴파일러가 해당 타입의 안정성을 정적으로 완전히 분석할 수 있는 경우에 해당합니다.
구체적인 예시는 다음과 같습니다.
-
Certain(stable = true)에 해당하는 타입들은 아래와 같습니다.- 원시 타입:
Int,Long,Float,Double,Boolean,Char,Byte,Short String,Enum클래스- 함수 타입:
() -> Unit,(Int) -> String
- 원시 타입:
-
Certain(stable = false)에 해당하는 타입들은 아래와 같습니다.var프로퍼티를 가진 클래스:data class MutableUser(var name: String)- 가변 컬렉션:
MutableList<String>,MutableMap<String, Int> - 불안정한 프로퍼티를 포함하는 클래스