본문 바로가기
프로그래밍/Kotlin

[Kotlin] lateinit과 lazy란? - 지연 초기화를 통한 성능 개선

by tempus 2021. 12. 24.
반응형

 

오늘은 Kotlin의 지연 초기화에 대해 알아봅시다. 초기화라는 말은 익숙하게 들어서 쉽게 이해할 수 있지만 지연(Lazy) 같은 경우는 프로그램에서는 기존과 다르게 다음과 같이 해석됩니다.

프로그램에서 Lazy는 퍼포먼스를 높이기 위해 처음부터 모든 것을 초기화하는 것이 아니라 필요한 순간까지 최대한 초기화를 지연시킨다는 의미로 사용한다.

 

지연 초기화는 왜 사용하는 것일까?

보통 class에서 변수를 초기화하면, 클래스 생성 시 해당 변수도 함께 생성되며 초기화됩니다. 그렇게 되면 클래스 객체를 생성할 때마다 해당 변수도 함께 초기화되기 때문에 바로 사용할 수 있다는 장점이 있습니다.

하지만 해당 변수를 바로 사용하지 않거나 꼭 사용하는 경우가 아니라면 클래스를 생성할 때마다 변수를 초기화하기 때문에 메모리나 소프트웨어의 실행 시간 측면에서 손해를 많이 보게 될 것입니다.

정리하면 지연 초기화는 해당 변수가 필요한 순간까지 초기화를 최대한 미루어서 메모리나 실행 시간에서 이득을 보기 위해 사용합니다.

 

Kotlin에서 지연 초기화를 2가지 방법으로 제공합니다.

 

lateinit

class LazyInitialization {
    private lateinit var name: String
}

초기화 지연 프로퍼티(Late-initialized property)라고 하며 프로퍼티의 초기화를 나중에 하기 위해 사용하는 키워드입니다. 항상 사용할 수는 없고 다음과 같이 몇 가지 제약 사항이 있습니다.

 

  • var(mutable) 에서만 사용이 가능
  • var이기 때문에 언제든 초기화를 변경할 수 있음
  • null을 통한 초기화를 할 수 없음
  • primitive type 사용 불가능
  • 초기화를 하기 전에는 변수에 접근 불가
  • 변수에 대한 custom setter/getter properties 정의가 불가능
  • 로컬 변수로 사용 불가능

 

그리고 해당 변수가 초기화되었는지 확인하기 위해서는 다음과 같은 코드를 사용하면 됩니다. (return값은 Boolean)

if (::변수.isInitialized) {
    // check then do something
}

 

lazy

private val adapter: BookListAdapter by lazy { 
        BookListAdapter()
}

lateinit과 마찬가지로 초기화를 지연시킬 때 사용합니다. 차이점은 선언과 동시에 초기화할 값을 지정해줍니다. 이후에 호출 시점에 lazy { }에 정의한 값을 초기화합니다. lazy도 다음과 같은 제약사항이 있습니다.

 

  • val (immutable) 에서만 사용이 가능
  • 값 교체 불가능
  • 로컬 변수에 사용 가능
  • primitive type에도 사용 가능
  • 클래스 생성자에서 사용 불가능
  • 변수에 대한 custom setter/getter properties 정의가 불가능
  • lazy 를 사용하는 경우 기본 Synchronized로 동작한다 ⇒ Thread-safe 하다

 

마치며

처음에는 지연 초기화의 개념도 모르고 무작정 사용했는데 한 번 정리를 하고 나니 어떻게 사용해야 할지 좀 더 명확하게 알 수 있었습니다. 이 글을 정리하면서 단순히 기능만을 사용하던 저를 보며 반성을 하게 되었습니다. 앞으로는 기능에 대한 정리와 이해를 기반으로 구현하는 습관을 기를 수 있도록 노력해야겠습니다.

반응형

댓글


loading