똑같은 기능의 객체를 매번 생성하기 보다는 재사용하는 것이 좋다.
예로 불변객체인 String 객체는
int i = 0;
while(i < Integer.MAX_VALUE) {
// String a = new String("a"); // 평균 0.05초
String a = "a"; // 평균 0.002초
i++;
}
new 생성자로 매번 생성시 쓸데없는 String 인스턴스가 수백만개 생겨난다.
하지만 String 리터럴 사용시 String Contants Pool에 저장되어 재사용되어지므로 생성 되지않는다.
속도 면에서도 차이가 나는걸 볼 수 있다.
또 다른 예로는 Boolean(String) 생성자(자바 9 이상 deprecated) 와 Boolean.valueOf(String)가 있다.
마찬가지로 Boolean(String) 생성자는 호출마다 객체를 생성하고,
Boolean.valueOf(String) 팩터리 메서드는 내부의 캐싱된 객체를 재사용한다.
public static Boolean valueOf(String s) {
return parseBoolean(s) ? TRUE : FALSE;
}
생성비용이 큰 객체일 경우 반복 생성 시 성능저하에도 영향이 있다.
로마 숫자인지 확인하는 메서드를 예로
static boolean isRomanNumeral(String s) {
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}
String.matches(String) 메서드를 사용시 반복 사용시 Pattern 객체를 생성하고, 사용, 참조해제가 반복되어 성능이 저하된다. 특히 Pattern객체는 입력받은 정규표현식에 해당하는 유한 상태 머신을 만들기 때문에 생성비용이 더욱 높다.
* 유한상태머신
한번에 한가지 상태를 가지는 수학적 모델
이벤트에 의해 상태가 변할 수 있고 안정성이 높다.
밑에 소스 처럼 객체를 직접 생성해 캐싱하여 사용하면 성능과 가독성을 높여준다.
public static final Pattern pattern = Pattern.compile("^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
static boolean isRomanNumeral(String s) {
return pattern.matcher(s).matches();
}
Map 인터페이스의 keySet 메서드
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
불필요한 객체를 만드는 예로는 오토박싱이 있다.
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i; // 오토박싱 되어 연산수행 마다 Long이 생성됨
}
성능 저하를 불러올 수 있으니 이러한 코드를 주의해야한다.
물론 무작정 객체 생성을 피하라는 뜻이 아닌 "불필요"한 객체 생성을 줄이자는 뜻이다.
요즘의 JVM은 작은 객체의 생성, 회수는 크게 부담되지 않고, 객체 생성으로 명확하고 간결해 질 수 있다.
위의 예제들 처럼 명확하게 객체가 재사용되어도 문제가 없을때만 재사용하고, 객체를 생성하는 편이 나을 수 도 있다.
객체 생성을 함으로써 생기는 문제는 성능 저하 수준이지만 재사용 시 생기는 버그는 피해가 더욱 클 수 있기 때문이다.
'프로그래밍 > JAVA' 카테고리의 다른 글
[JAVA] Effective Java - 7. 다 쓴 객체 참조를 해제하라 (0) | 2022.11.22 |
---|---|
[JAVA] Effective Java - 5. 자원을 직접 명시하지 말고 의존 객체 주입 사용 (0) | 2022.09.14 |
[JAVA] Effective Java - 4. 인스턴스화를 막으려면 private 생성자를 사용 (0) | 2022.09.06 |
[JAVA] Effective Java - 3. private 생성자나 열거 타입으로 싱글턴 보증 (0) | 2022.08.31 |
[JAVA] Effective Java - 2. 점층적 생성자, 자바 빈즈, 빌더 패턴 (0) | 2022.08.17 |