Book Record/Effective Java 3E

[Effective Java] 불필요한 객체 생성을 피하라

lakelight 2022. 12. 1. 13:24
728x90
반응형

 

 

똑같은 기능의 객체를 매번 생성하기보다
객체 하나를 재사용하는 편이 나을 때가 많습니다.

 

String 객체 생성 시

String string = new String("value");
다음과 같은 코드는 실행될 때마다 String 인스턴스를 새로 만들게 됩니다. 그래서 반목문이나, 자주 호출되는 메서드에 포함되어 있다면 사용하지 않는 인스턴스가 많이 생성될 수 있습니다.

String string = "value";
다음과 같은 코드를 통해 위에서 문제점을 개선할 수 있습니다. 새로운 인스턴스를 생성하는 대신 하나의 String 인스턴스를 재활용하여 사용합니다. 이와 같은 방식을 사용할 때, 가상 머신 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드가 같은 객체를 재사용함이 보장됩니다.

 

Boolean 객체 생성 시

Boolean boolean = new Boolean("true");

Boolean boolean = Boolean.valueOf("true");
생성자 대신 정적 팩터리 매서드를 제공하는 불변 클래스에서는 정적 팩터리 메서드를 사용해 불필요한 객체 생성을 피할 수 있습니다. 

 

정규 표현식을 사용할 때 성능을 올릴 수 있는 방법

public class PatterTest{
    private static final Pattern patternTest = Pattern.compile("^[가-힣a-zA-Z]{2,10}&");
    
    static boolean isPatternTest(String inputString){
    	return patternTest.matcher(inputString).matches();
    }
}
isPatternTest를 호출되는 상황에서 성능을 끌어올릴 수 있습니다. 성능뿐만아니라 코드도 명확해졌습니다. Pattern 인스턴스를 static final 필드로 끄집어내고 이름을 지어주어 코드의 의미가 훨씬 잘 드러나게 되었습니다.

 

불필요한 객체를 생성하는 오토박싱 

오토박싱

오토박싱은 기본 타입과 그에 대응하는 박싱된 기본 타입의 구분을 흐려주지만, 완전히 없애주는 것은 아닙니다.

오토박싱의 예

private static long totalLongSum(){
    Long totalSum = 0L;
    for(long l = 0; l <= Integer.MAX_VALUE; l++)
    	totalSum += l;
    
    return totalSum;
}
totalSum의 변수를 long이 아닌 Long으로 선언해서 불필요한 Long 인스턴스가 2^31개나 생성되었습니다. Long은 +1을 해줄 때 마다 new Long("value")값으로 새로운 인스턴스를 생성하기 때문입니다.

Long 타입을 long으로 변경한다면 성능이 6300ms -> 590ms 로 줄어들 것 입니다.
박싱된 기본 타입보다는 기본 타입을 사용하고, 의도치 않은 오토박싱이 숨어들지 않도록 주의해서 코딩해야 합니다.

 

마무리

이번 주제에서는 앞에서 배웠던 내용을 복습하는 개념이었습니다.

또한 박싱된 기본타입을 사용하므로서 성능을 떨어뜨릴 수 있다는 점과,
객체를 재활용하여 쓰도록 코딩해야 한다는 점을 다시 한번 알게되었습니다.

감사합니다.

 

[출처]

이펙티브 자바 Effective Java 3/E - 조슈아 블로크 저/ 개앞맵시 

 

728x90
반응형