StringBuilder의 append()와 String의 +연산자의 속도차이
자바에서 String은 변경이 안되는 객체이기 때문에 +연산을 하면 내부적으로 새 메모리를 할당받아서 사용한다고 한다. 그래서 String의 변경이 많은 경우에는 StringBuilder를 사용한다. 그런데 이 둘의 속도차이는 대략 어느정도 나는지, 정확히 어떤 부분에서 차이가 발생하는지 궁금해서 테스트해봤다.
테스트코드
초반 tc가 결과값이 좀 튀어서 앞의 두번 정도 계산하지 않고 12번 돌렸다.
출력창의 (final O)표시는 무시해도 된다. 출력창 문자열 지우는걸 깜빡했다. final과 일반 string을 둘다 테스트해봤는데 내 컴퓨터에서는 유의미한 차이가 나지 않아서 코드를 지웠다.
public static void main(String[] args) {
long start, end, sbtime = 0, strtime = 0;
for (int tc = 0; tc < 10; tc++) {
start = System.nanoTime();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i);
}
end = System.nanoTime();
sbtime += (end - start);
System.out.println("SB append(final O): " + (end - start));
start = System.nanoTime();
String str = "";
for (int i = 0; i < 10000; i++) {
str = str + i;
}
end = System.nanoTime();
strtime += (end - start);
System.out.println("String +(final O): " + (end - start));
System.out.println("======================================");
}
System.out.println("SB append avg: " + sbtime / 10);
System.out.println("String + avg: " + strtime / 10);
}
테스트 코드 결과
굳이 정확하게 계산하지 않아도 StringBuilder와 String연산은 자리수 두세개가 차이난다.
StringBuilder의 append() 실행 순서
StringBuilder의 append()는 이미 [이 글]에서 설명했기때문에 넘어간다.
String의 +연산자 실행 순서
위의 코드 중 str=str+i는 부를 때마다 최초로 StringBuilder() 객체를 만들고, append()함수를 두 번 부른다. 그리고 마지막에 StringBuilder()객체를 toString()을 이용해 new String()을 만든다.
풀어서 생각해보면 이런식이다.
str = new StringBuilder().append(str).append(i).toString();
//StringBuilder.java
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
그러면 당연히 str=str+i연산은 처음부터 StringBuilder만을 이용해서 연산하는 것과 비교해서 (객체생성시간+toString()시간)*반복수만큼 차이가 나게된다.
결론
String은 java에서 최적화를 시킨 덕분에 현재는 +연산을 할 때마다 새로 메모리가 생성되지는 않지만, 빠른 연산을 위해서 StringBuilder 객체를 생성하므로 그 시간을 항상 염두해두어야한다. 모두 append한 뒤에는 toString()메서드로 새 String을 생성하는 것도 알아두면 좋을 것 같다.
'기록 > JAVA' 카테고리의 다른 글
[JAVA] 예외처리의 비용 (0) | 2022.04.30 |
---|---|
[JAVA] library, framework, pattern, architecture 차이 (0) | 2022.04.19 |
[JAVA] String.format 과정 (0) | 2022.04.08 |
[JAVA] 전위연산, 후위연산 메모리 및 속도 차이 (0) | 2022.03.14 |
[JAVA] StringBuilder의 insert, append (0) | 2022.03.10 |
댓글