Kotlin/Effective Kotlin 요약
-
52장 - mutable 컬렉션 사용을 고려하라Kotlin/Effective Kotlin 요약 2023. 4. 16. 00:01
불변 컬렉션과 가변 컬렉션의 성능 가변 컬렉션이 성능적인 측면에서 조금 더 빠릅니다. 불변 컬렉션에 요소를 추가하는 것이 이해 안 될 수 있지만 요소를 추가하려면 새로운 컬렉션을 만들어서 요소를 추가해야 합니다. 컬렉션을 복제하는 것은 비용이 많이 듭니다. 안정성 하지만 아이템1에서 이야기했듯이 불변 컬렉션을 사용하게 되면 동기화와 캡슐화 측면에서 안전합니다. 결론 지역변수를 사용할 때는 가변 컬렉션을 사용하는 것이 더 합리적입니다. 표준 라이브러리도 내부적인 처리를 수행할 때는 가변 컬렉션을 사용하도록 구현되어 있습니다.
-
51장 - 성능이 중요한 부분에는 기본 자료형 배열을 사용하라Kotlin/Effective Kotlin 요약 2023. 4. 15. 00:01
기본자료형 배열과 컬렉션 List, Set 등의 컬렉션은 제네릭 타입입니다. 제네렉 타입에서는 기본 자료형을 사용할 수 없어 랩핑된 타입을 사용해야 합니다. 하지만 성능이 중요한 코드라면 IntArray와 LongArray 등의 기본 자료형을 활용하는 배열을 사용하는 것이 좋습니다. 보통 라이브러리 개발자, 게임 개발자, 고급 그래픽을 처리해야 하는 개발자들에게 도움이 됩니다. 성능의 차이(IntArray vs List) 1,000,000개(백만)의 정수를 갖는 컬렉션을 만든다고 가정하겠습니다. 단순하게 할당되는 영역(5배 차이) IntArray 400,000,016바이트 List 2,000,006,944바이트 성능(25% 차이) 단순하게 평균을 구하는 처리를 수행하면 기본 자료형 배열이 25% 정도 더..
-
50장 - 컬렉션 처리 단계 수를 제한하라Kotlin/Effective Kotlin 요약 2023. 4. 14. 00:01
컬렉션의 비용 모든 컬렉션 처리 메서드는 비용이 많이 듭니다. 내부적으로 요소들을 활용해 반복을 돌며, 추가적인 컬렉션을 만들어 사용하기도 합니다. 시퀀스도 시퀀스 전체를 랩 하는 객체가 만들어지며, 조작을 위해 또 다른 추가적인 객체를 만들어냅니다. 컬렉션의 처리의 단계 수 컬렉션과 시퀀스의 처리 수가 많다면 꽤 큰 비용이 들어갑니다. 어떤 메서드를 사용하는지에 따라서 컬렉션 처리의 단계 수가 달라집니다. 따라서 적절한 메서드를 활용해서 컬렉션 처리 단계 수를 적절하게 제한하는 것이 좋습니다. 이 코드보다는 이 코드가 좋습니다. .filter { it != null } .map { it } .filterNotNull() .map { Transformation } .filterNotNull() .mapN..
-
49장 - 하나 이상의 처리 단계를 가진 경우에는 시퀀스를 사용하라Kotlin/Effective Kotlin 요약 2023. 4. 13. 00:01
Iterable과 Sequence의 차이 interface Iterable { operator fun iterator() : Iterator } interface Sequence { operator fun iterator() : Iterator } 둘의 차이는 이름밖에 없는 것처럼 보입니다. 하지만 완전히 다른 목적으로 설계되어 있습니다. 서로 다른 filter 확장함수 구현 public inline fun Iterable.filter( predicate: (T) -> Boolean ): List{ return filterTo(ArrayList(), predicate) } public inline fun Sequence.filter( predicate: (T) -> Boolean ): List{ retu..
-
48장 - 더 이상 사용하지 않는 객체의 레퍼런스를 제거하라Kotlin/Effective Kotlin 요약 2023. 4. 12. 00:01
개요 보통 GC가 메모리 관리를 자동으로 해주기 때문에 객체의 해제를 따로 생각하지 않습니다. 하지만 메모리 관리를 전혀 신경 쓰지 않으면 메모리 누수가 발생하여 상황에 따라 OutOfMemoryError가 발생하기도 합니다. 따라서 ' 더 이상 사용하지 않는 객체의 레퍼런스를 유지하면 안 된다'라는 규칙 정도는 지켜 주는 것이 좋습니다. 안드로이드 개발자가 많이 하는 실수 Activity(데스크톱 애플리케이션의 창)을 여러 곳에서 자유롭게 접근하기 위해 companion 프로퍼티에 이를 할당해 두는 경우가 많습니다. 하지만 이렇게 되면 GC가 해당 객체에 대한 메모리를 해제할 수 없습니다. 액티비티는 굉장히 큰 객체로 큰 메모리 누수가 발생하게 됩니다. 책에서 보여주는 메모리 누수의 예시로는 compa..
-
47장 - 인라인 클래스의 사용을 고려하라Kotlin/Effective Kotlin 요약 2023. 4. 11. 00:01
개요 함수뿐만 아니라 클래스도 inline으로 만들 수 있습니다. inline 클래스 inline class Name(private val value: String){ //... } String을 name으로 래핑 해서 사용하고 있습니다. 하지만 inline을 활용하기 때문에 어떠한 오버헤드도 발생하지 않습니다. (inline으로 바로 호출해서 사용하기 때문에 래핑의 비용이 들지 않음) inline 클래스의 활용 보통 측청 단위를 표현할 때 타입 오용으로 발생하는 문제를 막을 때 측정 단위를 표현할 때 만약 time이라는 단어를 마주하면 이게 ms인지 s 인지 min인지 명확하지 않습니다. 가장 간단한 방법으로 파라미터 이름에 측정 단위를 붙여 줄 수 있습니다. 하지만 함수를 사용할 때 프로퍼티 이름이 ..
-
46장 - 함수 타입 파라미터를 갖는 함수에 inline 한정자를 붙여라Kotlin/Effective Kotlin 요약 2023. 4. 10. 00:01
개요 코틀린의 고차 함수(함수를 파라미터로 받는 함수 또는 함수를 리턴하는 함수)는 대부분 inline 한정자가 붙어있습니다. inline 한정자는 무엇일까요? inline 한정자 inline 한정자의 역할은 컴파일 시점에 '함수를 호출하는 부분'을 '함수의 본문'으로 대체합니다. 예를 들어 repeat 함수를 다음과 같이 구현되어 있습니다. inline fun repeat(times: Int, action: (Int) -> Unit){ for(index in 0 until times){ action(index) } } repeat을 호출하는 부분은 컴파일 시점 다음과 같이 대체됩니다. repeat(10){ println(it) } //컴파일 시점 for(index in 0 until 10){ print..
-
45장 - 불필요한 객체 생성을 피하라Kotlin/Effective Kotlin 요약 2023. 4. 8. 00:01
객체 생성의 비용 객체 생성은 언제나 비용이 들어갑니다. JVM에서는 하나의 가상 머신에서 동일한 문자열을 처리하는 코드가 여러 개 있다면, 기존의 문자열을 재사용합니다. 또한 Int는 -128 ~ 127 범위를 캐시해 둡니다. 객체 생성 비용은 항상 클까? 현재 64비트 JDK에서 객체는 8바이트의 배수만큼 공간을 차지합니다. 앞부분 12바이트는 헤더로서 반드시 있어야 하므로, 최소 크기는 16바이트입니다. 기본 자료형 int는 4바이트입니다. 하지만 오늘날 널리 사용되고 있는 64비트 JDK에 랩 되어 있는 Integer는 16바이트입니다. 추가로 이에 대한 레퍼런스로 인해 8바이트가 더 필요해 5배 이상의 공간을 차지한다고 볼 수 있습니다. 객체는 생성되어야 하며, 메모리 영역에 할당되고, 이에 대..