본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Effective Kotlin] Item 45: Avoid unnecessary object creation

by 돼지왕 왕돼지 2022. 6. 6.
반응형

이 글은 Effective Java 를 완독하고, Kotlin 을 상용으로 사용하는 개발자 입장에서
Effective Kotlin 글 중 새로운 내용, remind 할 필요 있는 부분, 핵심 내용 등만 추려 정리한 내용입니다.

 

#
동일 내용의 string literal 과 값이 작은 Boxed primitive 는 동일 JVM 안에서 재사용된다.
(Integer cache 는 -128~127 의 숫자를 들고 있다.)

 

#
Int? (nullable) primitive type 은 null 을 받아들여야 하기 때문에 Integer 로 사용되고, Int 의 경우 primitive int 가 사용된다.

 

 

Is object creation expensive?

#
Objects 는 추가 공간을 점유한다.
64-bit JDK 에서 12-byte header 와 8byte 배수를 맞추기 위한 패딩이 들어간다. 그래서 최소 사이즈가 16byte 이다.
32-bit JVM 에는 최소 사이즈가 8byte 이다.
object reference 자체도 공간을 차지한다. refernece 는 4~8byte 를 사용한다. (환경에 따라 다르다.)
그 자체의 비용은 작지만 그것들이 모이면 큰 비용이 된다.
primitive Int 는 4byte 지만 Integer 는 16byte 를 사용한다.

 

#
encapsulated 된 경우 function call access 비용이 발생한다.
function 이 빠르다면 작은 비용이지만, 반복 호출될 경우 역시나 큰 비용이 된다.
그렇다고 encapsulation 을 제한하는게 답이 아니다. 불필요한 object 생성을 막는 방향으로 가야 한다.

 

#
Objects 가 생성되어야 한다.
create, allocate memory, reference 가 되어야 한다.
이 과정 역시 비용이 적지만, 누적되면 큰 비용이 된다.

 

 

Object declaration

#
object 재사용의 가장 간단한 방법은 singleton 을 사용하는 것이다.

 

#
Nothing 은 모든 type 의 subtype 이다.

 

#
Immutable object 를 만들면 재사용이 또 쉬워진다.

 

 

Factory function with a cache

#
Cache 에는 WeakReference 보다 SoftReference 가 선호된다.
WeakReference 는 참조가 없어지면 바로 GC 대상이 되지만, SoftReference 는 참조가 없으면서 Memory 가 부족한 상황에서 GC 대상이 된다.

 

 

Heavy object lifting

#

fun <T: Comparable> Iterable.countMax(): Int{
	val max = this.max()
	return count { it == max }
	// return count { it == this.max() }
}

 

 

Lazy initialization

#
Lazy 도 양날의 검이라는 것 알고 사용할 것.

 

 

Using primitives

#
nullable type 사용 & generic 에 사용하는 경우 primitive 를 사용할 수 없음.

 

#
억지로 primitive 로 바꾸면서 가독성이 안 좋아지는 케이스가 많아지기 때문에,
퍼포먼스 이슈가 있어서 최적화가 필요할 때만 하는 것이 권장된다.

 

 

Summary

#
안정적인 최적화 방법들이 있다.
그러나 어설픈 최적화는 오히려 가독성을 해치고, 이상한 동작을 할 수도 있으니 잘 점검하자.

 

 

 

반응형

댓글