이펙티브 코틀린 7장 비용 줄이기

Rm·2022년 4월 11일
0

이펙티브 코틀린

목록 보기
7/8
post-thumbnail

7장. 비용 줄이기

아이템 45. 불필요한 객체 생성을 피하라

  • 객체를 Wrap 하게 되면 3가지 비용이 발생한다.
    • 헤더 및 레퍼런스를 위한 추가 공간
    • 요소가 캡슐화 되어있다면, 접근을 위한 함수 호출 비용
    • 객체 생성을 위한 메모리 공간 할당 및 레퍼런스 생성 비용
  • 캐싱 기법을 활용해서 객체를 재활용하면 불필요한 객체 생성으로 인한 비용을 줄일 수 있다.
    • 단, 캐시는 언제나 메모리와 성능의 트레이드 오프가 발생하기 때문에 여러가지 상황을 잘 고려해서 사용해야한다.
  • 무거운 클래스를 생성할 때 지연 초기화를 하는 것이 좋을 수 있다.
    • 하지만, 백엔드 애플리케이션과 같은 특수한 경우에는 지연초기화를 통해 첫번째 응답시간이 굉장히 길어지는 문제와 성능 테스트가 복잡해지는 단점을 가지고 있다.

아이템 46. 함수 타입 파라미터를 갖는 함수에 inline 한정자를 붙여라

  • inline 한정자의 역할은 컴파일 시점에 함수를 호출하는 부분을 함수의 본문으로 대체하는 것이다.
    • 일반적인 함수를 호출하면 함수 본문으로 점프하고 본문의 모든 문장을 호출한 다음, 함수를 호출했던 위치로 다시 점프하는 과정을 거친다.
    • inline 한정자를 사용하면 이러한 점프가 일어나지 않는다.
  • inline 한정자를 사용하면 다음과 같은 장점을 얻을 수 있다.
    • 타입 아규먼트에 reified 한정자를 붙여서 사용할 수 있다.
    • 함수 타입 파라미터를 가진 함수가 훨씬 더 빠르게 동작한다.
    • 비지역 리턴을 사용할 수 있다.
  • inline 한정자는 모든 곳에서 사용할 수 없다.
    • 재귀적으로 사용할 경우 무한하게 대체되는 문제가 발생한다.
    • 가시성 제한을 가진 요소를 사용할 수 없다.
    • inline 한정자를 남용하면 코드의 크기가 쉽게 커진다.
  • crossinline : 아규먼트로 인라인 함수를 받지만 비지역적 리턴을 하는 함수는 받을 수 없게 만든다.
    • 인라인으로 만들지 않은 다른 람다 표현식과 조합해서 사용할 때 문제가 발생하는 경우에서 활용한다.
  • noninline : 아규먼트로 인라인 함수를 받을 수 없게 만든다, 인라인 함수가 아닌 함수를 아규먼트로 사용하고 싶을 때 활용한다.

아이템 47. 인라인 클래스의 사용을 고려하라

  • 프로퍼티가 단 하나만 존재하는 클래스는 inline 한정자를 붙여서 inline 클래스로 만들 수 있다.
    • inline 클래스는 해당 객체를 사용하는 위치가 모두 해당 프로퍼티로 교체된다.
    • inline 클래스의 메서드는 모두 정적 메서드로 만들어진다.
  • inline 클래스는 다른 자료형을 Wrapping해서 새로운 자료형을 만들 때 많이 사용된다.
  • inline 클래스도 인터페이스를 구현할 수 있지만, 인터페이스를 구현하는 inline 클래스는 inline 으로 동작하지 않는다.
    • 인터페이스를 통해서 타입을 나타내려면, 객체를 Wrapping해서 사용해야하기 때문에 인터페이스를 구현하는 inline 클래스는 아무런 의미가 없다.
  • typealias 를 이용해서 타입에 새로운 이름을 붙여줄 수 있으며, 이는 길고 반복적으로 사용해야할 때 유용하다.
    • typealias 는 단순하지만 안전하지 않으며, 이를 잘못 사용한 경우에도 어떠한 요류가 발생하지 않기 때문에 문제를 찾는 것을 더 어렵게 만든다.
    • 때문에 비용과 안전이라는 두 가지 측면을 위해서는 inline 클래스를 사용하자.

아이템 48. 더 이상 사용하지 않는 객체의 레퍼런스를 제거하라

  • 가비지 컬렉터를 맹신하고 메모리 관리를 완전히 무시해버리면, 메모리 누수가 발생하여 최악의 경우 OOME가 발생할 수 있다.
    • 때문에 더 이상 사용하지 않는 개체의 레퍼런스는 유지하면 안된다라는 규칙 정도는 지켜주는 것이 좋다.
  • 객체에 대한 참조를 companion 또는 static 으로 유지해버리면, 가비지 컬렉터가 해당 객체에 대한 메모리 해제를 할 수 없다.
    • 특히, Activity와 같은 큰 객체를 이렇게 선언할 경우 메모리를 해제할 수 없어 굉장히 큰 메모리 누수가 발생하게 된다.
    • 때문에 비용이 큰 객체는 리소스를 정적으로 유지하지 않는 것이 가장 좋다.
  • 범용적으로 사용하는 라이브러리는 어떻게 사용될지 예측하기 어렵기 때문에 최적화에 신경을 더 써야한다.
    • 때문에 사용하지 않는 오브젝트에 명시적으로 null 을 할당하여 초기화하자.
profile
우당탕 개발자 성장기

0개의 댓글