Skip to main content

Primitive type이 Reference type 보다 빠른 이유

이펙티브 자바 8장을 사내 스터디를 위해 정리하다가 정리해두면 좋을 정보를 블로깅합니다.
(모두가 알고 있는 내용이지만 발표를 위해 직접 테스트까지 해서. 그냥 지우기 아까워서 ㅋㅋㅋ)

 -> (비교 연산이 목적이라면) 객체화된 reference type 대신 primitive type을 이용하라.
 -> 비교연산이 아닌 Method 의 경우라면 신중하게 고민 후 선택하라.

!. 속도차가 많이 나기 때문이다.




속도차가 나는 이유.

1. Heap 메모리 할당 비용이 크다.
primitive type 인 변수 n1 는 stack에 저장된다.
reference type인 n2는 stack에 저장되지만, heap 메모리도 할당을 받는다.

1.2. Stack과 Heap은 운영체제(JVM)에서 처리하는 방식도 다르다.
운영체제에서 두 메모리 저장 장소를 처리하는 방식의 차이가 있다.
stack은 비교적 예측 가능한 크기의 메모리가 할당되고 , Heap은 가변적 크기의 메모리가 할당된다.
또 Heap보다 Stack이 캐싱될 확률이 높다.





아래는 메모리 사용량을 테스트 하는 코드이다.

primitive type인 'double' 사용


결과: Used memory: 692160


reference type인 'Double'을 사용.

결과: Used momory: 1384336


reference type이 메모리를 많이 잡아먹는 것을 확인헀다.
이제는 속도를 비교해 본다.

Eclipse 마켓에 있는 'JBenchX' 를 사용하여 Benchmark를 했다.




단순한 연산 10,000 개를 벤치마크한 결과
double은 2ms, Double은 5.5ms 로 약 2배 이상 속도 차이가 나는 것으로 확인됐다.
String 이어붙이기는 n의 제곱 (n2) 만큼 시간이 걸린다고 책에 나와있습니다.

그래서 (비루하지만...) 다섯 번 실험을 해보았습니다.

50번 비교:  119us,  31.0us
100번 비교:  315us,  62.0us
1000번 비교: 1.62ms, 66.0us
5000번 비교:  46.7ms,  167us
10000번 비교: 225ms,  330us


!. 무조건 primitive 형을 써야하나요?
a> 꼭 그렇진 않습니다. 반환타입이 int 인 메소드의 경우 0으로 반환 시 null인지 의미가 있는 숫자 0인지 알 길이 없습니다. 이런 경우는 Integer를 사용하여 명확하게 할 수 있습니다.
이게 바로 reference type (Integer, String 등)의 탄생 배경입니다. 또 Java가 완전한(pure) 객체지향 언어가 아니라는 말이 나오는 이유이기도 합니다.
( Scala 언어 같은 경우 primitive type이 없습니다.)

(추상적인 무서운 표현이지만) ‘적절'하게 사용해야 겠습니다.


-


Comments