아티클 목록으로 가기

Jetpack Compose SlotTable 내부 구조 심층 분석

skydovesJaewoong Eum (skydoves)||7분 소요

Jetpack Compose SlotTable 내부 구조 심층 분석

SlotTable은 Jetpack Compose 애플리케이션의 UI 트리를 메모리에 표현하는 핵심 자료구조입니다. 일반적인 객체 트리 형태가 아니라, 매우 빠른 UI 업데이트를 위해 고도로 최적화된 플랫(flat) 구조로 설계되어 있습니다. 이 글에서는 SlotTable의 소스 코드를 직접 살펴보면서 내부 동작 원리를 깊이 있게 분석합니다.

Compose 런타임이 선언적 UI를 빠르게 업데이트할 수 있는 비결이 바로 이 SlotTable에 있으므로, Compose의 내부 동작을 이해하고 싶은 분이라면 꼭 한 번 살펴보시길 권장합니다.

1. 핵심 데이터 모델: groupsslots

SlotTable의 핵심에는 두 개의 병렬 플랫 배열이 자리잡고 있습니다. 이것이 가장 먼저 이해해야 할 핵심 개념입니다.

internal class SlotTable : CompositionData, Iterable<CompositionGroup> {
    /**
     * 그룹 정보를 저장하는 배열로, 인라인 구조체(inline struct)의 배열과 같은 역할을 합니다.
     */
    var groups = IntArray(0)
        private set

    /**
     * 각 그룹에 대한 슬롯 데이터를 저장하는 배열입니다.
     */
    var slots = Array<Any?>(0) { null }
        private set
    //...
}
  • groups: IntArray: UI의 설계도에 해당합니다. 컴포저블의 구조메타데이터를 원시 타입(primitive type) 배열에 압축하여 저장합니다. 각 컴포저블 호출의 계층 구조, 키, 속성을 기술하는 고효율 인라인 명령 목록이라고 생각하면 이해하기 쉽습니다. 플랫 IntArray이므로 CPU가 메모리 포인터를 따라 점프하는 비용(pointer chasing) 없이 매우 빠르게 순차 탐색할 수 있습니다.

  • slots: Array<Any?>: 실제 데이터 저장소입니다. remember로 기억한 값, 상태(state) 객체, 람다, UI 노드(LayoutNode) 등 컴포저블이 생성한 실제 데이터와 객체를 보관합니다.

groups 배열은 Compose 런타임에 slots 배열을 어떻게 해석해야 하는지 알려주는 역할을 합니다. 이 설계는 객체지향적 편의성보다 캐시 친화적 순회(cache-friendly traversal)를 우선시하는 전형적인 데이터 지향 설계(data-oriented design) 기법입니다.

2. 명명 규칙과 "인라인 구조체"

SlotTable.kt 파일 상단의 주석은 전체 코드를 이해하기 위한 용어 사전과 같습니다. 그중 가장 중요한 개념이 바로 그룹(Group) 입니다.

그룹은 클래스가 아닙니다. groups 배열 내에서 연속된 5개의 정수로 이루어진 논리적 단위를 의미하며, 이것이 주석에서 "인라인 구조체(inline struct)"라고 표현한 개념입니다.

// 그룹 레이아웃
//  0             | 1             | 2             | 3             | 4             |
//  Key           | Group info    | Parent anchor | Size          | Data anchor   |
private const val Group_Fields_Size = 5

이 구조체는 비트 연산을 수행하는 확장 함수(extension function)를 통해 접근하므로 속도가 매우 빠릅니다. 예를 들어, 특정 그룹이 UI 노드를 나타내는지 확인하려면 다음과 같이 처리합니다.

이 아티클은 구독자 전용입니다

Dove Letter를 구독하시면 안드로이드, 코틀린 개발 관련 독점 아티클의 전체 내용을 볼 수 있습니다.

구독하기
아티클 목록으로 가기