질문의 역사:
Kotlin에서 프로퍼티에 대한 접근은 getter 및 setter 메서드를 통해 이루어집니다. 성능을 높이기 위해 개발자는 inline 수정자를 접근자에 추가하여 JVM이 컴파일 시 get/set의 본체를 호출하는 코드에 직접 삽입할 수 있도록 최적화했습니다.
문제:
일반 접근자 메서드는 각 프로퍼티에 대해 생성되므로 호출의 오버헤드가 증가합니다 (특히 자주 호출될 경우). 때때로 개발자는 별도의 get/set로 로직을 분리하지만 함수 호출의 오버헤드를 피하고 싶어합니다.
해결책:
getter 또는 setter의 구현이 짧고 무거운 코드가 없을 경우 inline 수정자를 사용하세요. 이는 오버헤드를 줄이며, 특히 핫 패스에서 유리합니다. 인라인은 JVM 상속 원리 때문에 일반 클래스의 프로퍼티가 아닌 top-level 프로퍼티 및 companion object 및 object 객체의 프로퍼티에만 작동합니다.
코드 예:
inline var Int.asHex: String get() = Integer.toHexString(this) set(value) {} inline val String.firstUpperCase: String get() = if (isEmpty()) this else this[0].uppercase() + substring(1)
주요 특징:
일반 클래스 프로퍼티에 대해 인라인 get/set을 사용할 수 있나요?
아니요, getter 및 setter의 인라인은 top-level 또는 object (companion object 포함) 프로퍼티에만 허용되며, 클래스 내부의 프로퍼티에는 허용되지 않습니다.
인라인 접근자에서 backing field(지원 필드)에 접근할 수 있나요?
아니요, 인라인 접근자는 backing field를 가지지 않으며, 이를 참조하려고 하면 컴파일 오류가 발생합니다.
인라인 접근자가 항상 바이트코드에 영향을 미치나요?
인라인은 컴파일러에게 코드를 내장할 수 있다는 신호를 줄 뿐입니다. JIT 컴파일러는 특정 경우 이를 무시할 수 있습니다. 또한, 접근자가 무거운 로직을 포함한다면, 얻는 효과가 반대일 수 있습니다.
프로젝트에서 큰 프로퍼티를 인라인으로 선언했지만, getter에서 무거운 변환을 처리하여 반복문에서 사용했습니다. 결과적으로 최종 바이트코드가 부풀어지고 JIT가 인라인을 비활성화하여 성능이 저하됩니다.
장점:
단점:
숫자를 문자열로 변환하기 위해 인라인 val을 선언했습니다. getter는 UI 코드에서 자주 호출됩니다. 성능은 여전히 높고 바이트코드는 간결합니다.
장점:
단점: