Language/Java

StringBuilder를 초기화 하는 방법 3가지 성능 비교

JaeHoney 2021. 10. 7. 00:58

 

StringBuilder와 StringBuffer는 String의 불변성(Immutable) 때문에 연산이 많아질수록 속도, 메모리 효율 등 퍼포먼스가 크게 떨어지는 점을 극복하기 위해서 사용하는 대표적인 클래스입니다.

 

알고리즘 문제를 풀 때는 비동기적이지만 퍼포먼스가 뛰어난 StringBuilder를 주로 사용하죠.

 

보통 반복문에서 지역변수를 사용할 때는 어떻게 사용하시나요?

 

그럼 StringBuilder는?

 


 

 

Q. 아래는 반복문에서 지역변수를 사용하는 예시 2가지입니다. 다음 코드 중 더 좋은 코드는 몇 번 일까요?

  1. 변수를 매번 새로 할당하는 방법
  2. 변수를 1번만 할당하고 초기화하는 방법
// 1번
int num = 0;
for(int c : array) {
    num = c + 10;
    System.out.println(num);
}
// 2번
for(int c : array) {
    int num = c + 10;
    System.out.println(num);
}

'당연히'라고 할수는 없지만, 아마 대부분의 개발자가 1번을 선택할 것입니다.

가장 작은 범위에서 객체나 변수를 선언하면 가독성이 향상되고 유지보수 관점에서 1번이 더 좋습니다.

 

하지만, 문득 이런 생각이 들었습니다.

기본 자료형이야 그렇다고 하지만, StringBuilder는 엄청 무거울텐데... 계속 새로 할당해??

 

 


 

그래서 비교해봤습니다.

  1. StringBuilder를 매번 새로 생성
  2. StringBuilder를 1번만 생성하고 sb.delete()로 초기화 후 재사용
  3. StringBuilder를 1번만 생성하고 sb.setLength()로 초기화 후 재사용
public class Test {

    static String a;

    public static void main( String[] args ) throws Exception {
    
        // 1. 매번 새로 할당
        long time = System.currentTimeMillis();
        for( int i = 0; i < 10000000; i++ ) {
            StringBuilder sb = new StringBuilder();
            sb.append( "someString1" );
            sb.append( "someString2" );
            sb.append( "someString3" );
            sb.append( "someString4" );
            sb.append( "someString5" );
            a = sb.toString();
        }
        System.out.println("매번 새로 할당 : " + (System.currentTimeMillis()-time));
        
        // 2. delete()로 초기화
        time = System.currentTimeMillis();
        StringBuilder sb2 = new StringBuilder();
        for( int i = 0; i < 10000000; i++ ) {
            sb2.delete( 0, sb.length() );
            sb2.append( "someString" );
            sb2.append( "someString2" );
            sb2.append( "someString3" );
            sb2.append( "someString4" );
            sb2.append( "someString5" );
            a = sb2.toString();
        }
        System.out.println("sb.delete()로 초기화 : " + (System.currentTimeMillis()-time));
        
        // 3. setLength(0)으로 초기화
        time = System.currentTimeMillis();
        StringBuilder sb3 = new StringBuilder();
        for( int i = 0; i < 10000000; i++ ) {
            sb3.setLength(0);
            sb3.append( "someString1" );
            sb3.append( "someString2" );
            sb3.append( "someString3" );
            sb3.append( "someString4" );
            sb3.append( "someString5" );
            a = sb3.toString();
        }
        System.out.println("sb.setLength()로 초기화 : " + (System.currentTimeMillis()-time));
    }

}

결과는 이렇습니다. 예상했던 대로 새로 할당하는 방법이 가장 오래걸리고, 나머지 두 방법은 거의 비슷하네요.

그래도 10번 정도 실행했는데 대부분 setLength(0)으로 초기화하는 방법이 가장 빠르긴 합니다.

  1. 매번 새로 할당 : 1326
  2. sb.delete()로 초기화 : 647
  3. sb.setLength()로 초기화 : 639

 

어떻게 보시나요??

으음.. 사실 뭐 정답은 없겠습니다. 정석은 당연히 1번이겠지만, 뭐 퍼포먼스가 매우 매우 중요한 환경이라고 한다면 3번도 나쁘지 않아 보입니다.

 

이상입니다..!