같은 기능을 하는 객체를 여러 번 사용하는 것 보다 객체 하나를 재사용 하는 것이 더 나을 때가 있다.
String s1 = new String("java");
String s2 = new String("java");
System.out.println(s1 == s2); // false
String s3 = "java";
String s4 = "java";
System.out.println(s3 == s4); // true
s1
, s2
의 생성 방법은 java
라는 문자열을 매번 새로 생성하지만,
s3
, s4
는 **String Constant Pool**을 사용하여 java
라는 문자열을 캐싱하여 사용한다.
Wrapper Class에서는 캐싱을 지원해주는 valueOf()
라는 메소드가 존재한다.
대표적으로 자주 사용하는 Boolean
의 경우에는 true/false를,
Short
, Integer
와 Long
의 경우에는 -128 ~ 127까지의 수의 캐싱을 지원해준다.
Integer i1 = new Integer(50);
Integer i2 = new Integer(50);
System.out.println(i1 == i2); // false
Integer i3 = Integer.valueOf(50);
Integer i4 = Integer.valueOf(50);
System.out.println(i3 == i4); // true
Integer i5 = 50;
Integer i6 = 50;
1.8에서는 굳이 valueOf()
를 추가할 필요가 없다. 😅
- 크기가 아주 큰 Array
- Database Connection
- I/O 작업을 필요로 하는 Object
- (책에 나오는) Pattern
public class Caching {
private static int[] cachingArray = new int[500000];
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
// 1. 캐싱을 했을 때
for (int i = 0; i < 200000; i++) {
cachingArray[i] = 1;
}
System.out.println("캐싱 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000);
// 2. 캐싱을 하지 않았을 때
beforeTime = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
int[] nonCachingArray = new int[500000];
nonCachingArray[i] = 1;
}
System.out.println("캐싱 안 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000);
}
}
하지만 가벼운 객체는 그냥 만드는게 낫다. 오히려 객체를 캐싱하려다가 코드를 헷갈리게 하고 메모리 사용량을 늘려 성능을 떨어뜨리는 경우도 발생하게 된다.
Reference type - Primitive type 간 상호 변환해주는 기술
Integer a = 1;
int b = a + 2; // a를 int로 변환해준다.
하지만 오토박싱에도 변환 비용이 들기 때문에 의도하지 않은 오토박싱이 숨어들지 않게 주의해야한다.
public class AutoBoxing {
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
// 1. auto-boxing 사용 O
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println("auto-boxing 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000.0);
// 2. auto-boxing 사용 X
beforeTime = System.currentTimeMillis();
long sum2 = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum2 += i;
}
System.out.println("auto-boxing 안 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000.0);
}
}
객체 생성은 비싸니 피해야한다 (X)
생성 비용이 비싼 객체의 재사용을 고려해보자 (O)