StringBuilder와 StringBuffer는 String의 불변성(Immutable) 때문에 연산이 많아질수록 속도, 메모리 효율 등 퍼포먼스가 크게 떨어지는 점을 극복하기 위해서 사용하는 대표적인 클래스입니다.
알고리즘 문제를 풀 때는 비동기적이지만 퍼포먼스가 뛰어난 StringBuilder를 주로 사용하죠.
보통 반복문에서 지역변수를 사용할 때는 어떻게 사용하시나요?
그럼 StringBuilder는?
Q. 아래는 반복문에서 지역변수를 사용하는 예시 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는 엄청 무거울텐데... 계속 새로 할당해??
그래서 비교해봤습니다.
- StringBuilder를 매번 새로 생성
- StringBuilder를 1번만 생성하고 sb.delete()로 초기화 후 재사용
- 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)으로 초기화하는 방법이 가장 빠르긴 합니다.
- 매번 새로 할당 : 1326
- sb.delete()로 초기화 : 647
- sb.setLength()로 초기화 : 639
어떻게 보시나요??
으음.. 사실 뭐 정답은 없겠습니다. 정석은 당연히 1번이겠지만, 뭐 퍼포먼스가 매우 매우 중요한 환경이라고 한다면 3번도 나쁘지 않아 보입니다.
이상입니다..!
'Language > Java' 카테고리의 다른 글
Effective Java - Wrapper 클래스 사용 시 주의할 점 (오토 박싱, 오토 언박싱) (0) | 2022.01.14 |
---|---|
Effective Java - 생성자 대신 정적 팩토리 메서드를 사용하라! (0) | 2022.01.02 |
JAVA - 재귀함수 파라미터 vs 전역변수 (0) | 2021.09.17 |
JAVA - 프로젝트 패키지이름 명명(Naming) 관례 (0) | 2021.02.04 |
Java - 스택 트레이스(Stack Trace) 읽기 (3) | 2020.10.09 |