본문 바로가기
프로그래밍이야기/Java

[Item6] 불필요한 객체를 생성하지 마라

by 사랑꾼이야 2022. 1. 5.
반응형

Effective Java의 Item6에서는 불필요한 객체를 생성하지 마라고 설명을 하고 있습니다.
그 내용 중 여기서는 오늘 생성 비용이 큰 객체의 재사용의 대해서 한 가지 알아보려고 합니다.

사실, 이 내용은 피드백을 통해서 알게된 내용입니다.

 

1주차 우테캠 Pro 3기 회고

 

[1주차] 우테캠 Pro 3기 회고

1주차 미션은 문자열 덧셈기와 로또를 구현하는 미션을 진행하였습니다. 진행해왔던 미션을 회고하면서 놓쳤던 부분들을 정리하려고 합니다. 문자열 덧셈기 기간 미션 진행 기간 : 2021.11.02 ~ 2021

lovethefeel.tistory.com

 

그렇다면 객체의 생성 비용이 크다면 과연 성능상 얼마나 큰 차이가 있을까 궁금하였습니다.
그래서 다음과 같이 실험을 하였습니다.

 

개발 환경

  • Java : 1.8
  • Gradle : 6.8

 

객체를 재사용하지 않은 경우

쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열이 들어오는 경우 true를 반환하는 로직입니다.
아래 내용을 보면 Pattern 객체를 재사용하지 않고 있습니다.

 

public class CheckSeparatorAndDelimiterBefore {
    public static boolean checkSeparatorAndDelimiter(String str) {
        final Pattern PATTERN_DELIMITERS = Pattern.compile("[,:]");
        final Matcher matcher = PATTERN_DELIMITERS.matcher(str);
        if( matcher.find() ) {
            return true;
        }
        return false;
    }
}

 

단위테스트

  • 반복문 백만건 처리

 

    @DisplayName("문자열의 , 또는 : 가 포함되어 있다면 true를 반환한다.")
    @Test
    void checkSeparatorAndDelimiter() {
        // given
        final String 콤마포함 = ",123";

        // when
        Boolean result = false;
        final CheckSeparatorAndDelimiterBefore check = new CheckSeparatorAndDelimiterBefore();
        for (int i = 0; i < 1000000; i++) {
            if(result != null)
            result = check.checkSeparatorAndDelimiter(콤마포함);
        }

        // then
        assertThat(result).isTrue();
    }

 

단위테스트 결과

 

수행 시간을 보면 524ms가 소요되었습니다.
다음으로 객체를 재사용한 경우애 대해서 테스트를 진행해보겠습니다.

 

객체를 재사용한 경우

Pattern 객체를 재사용하여서 사용하고 있습니다.

 

public class CheckSeparatorAndDelimiterAfter {
    private static final Pattern PATTERN_DELIMITERS = Pattern.compile("[,:]");
    public static boolean checkSeparatorAndDelimiter(String str) {
        Matcher matcher = PATTERN_DELIMITERS.matcher(str);
        if( matcher.find() ) {
            return true;
        }
        return false;
    }
}

 

단위테스트

  • 반복문 백만건 처리

 

    @DisplayName("문자열의 , 또는 : 가 포함되어 있다면 true를 반환한다.")
    @Test
    void checkSeparatorAndDelimiter() {
        // given
        final String 콤마포함 = ",123";

        // when
        boolean result = false;
        final CheckSeparatorAndDelimiterAfter check = new CheckSeparatorAndDelimiterAfter();
        for (int i = 0; i < 1000000; i++) {
            if(!result)
            result = check.checkSeparatorAndDelimiter(콤마포함);
        }

        // then
        assertThat(result).isTrue();
    }

 

단위테스트 결과

 

수행 시간을 보면 114ms가 소요되었습니다.
객체를 재사용하지 않는 경우와 비교하였을때, 약4.5배 정도의 성능 차이가 나타남을 알 수 있습니다.

 

결론

작은 차이가 큰 성능 차이로 나타남을 알 수 있습니다.

 

비교 테이블

  객체 재사용X 객체 재사용
10건 106ms 106ms
100건 114ms 111ms
1000건 113ms 107ms
10000건 147ms 110ms
100000건 165ms 117ms
1000000건 521ms 111ms

 

반응형

댓글