티스토리 뷰

반응형

 String과 StringBuilder, StringBuffer는 모두 문자열을 저장 및 관리하는 클래스이다. 아래와 같은 방식으로 생성 가능하다.


String str1 = new String("abc");
String str2 = "abc";
StringBuilder str3 = new StringBuilder("abc");
StringBuffer str4 = new StringBuffer("abc");


 참고로, StringBuilder와 StringBuffer의 생성자의 파라미터로 CharSequence 인터페이스를 구현한 모든 클래스를 사용할 수 있다. CharSequence를 구현한 클래스로는 CharBuffer, String, StringBuffer, StringBuilder가 있다.



 String과 StringBuilder 및 StringBuffer의 가장 큰 차이는, String은 immutable(불변)하고, 나머지 두개는 mutable(가변)하다는 점이다. 이러한 차이는 String을 더하는(+)연산에서 확연히 차이난다. 스트링 객체 str1, str2를 더하여 str1에 저장하는 상황을 가정하고, 아래 그림을 보자.





 String은 immutable하기에, 문자열을 더하는 상황에서도 새로운 String객체가 생성된다. 게다가 기존에 사용하던 "abc"객체는 아무도 참조하지 않게 되어, GC(Garbage Collector)의 수거가 필요해졌다. 


반면, StringBuilder와 StringBuffer의 경우에는 같은 상황에서도 조금 다른 처리를 하게 된다. 아래 그림을 살펴보자.





 위와 같은 이유로, 문자열을 더할 때 String의 +연산 보다는 StringBuilder나 StringBuffer의 append()를 사용하는 것이 더 좋다. 하지만 이 사실을 잘 모르는 사람들도 꽤 있는데, JAVA 1.5 부터는 컴파일 단계에서 자동으로 변환 작업이 이루어지기 때문이다. 바로 아래와 같은 변환이다.


int i = 3;
String str = "abc"+"def"+i+"ghi"
/* 위 소스코드는 컴파일 시점에 아래와 같이 변경된다. */
int i = 3;
String str = (new StringBuilder("abc")).append(i)
                .append("def").append("ghi").toString();


 그렇다면 무조건 String의 +연산을 사용해도 되는걸까? 직접 실험해본 결과 항상 위와 같은 변환이 일어나는 것은 아니었다. 내 예상으로는 Runtime 시점에 일어나는 +연산은 StringBuilder 또는 StringBuffer의 append()로 변환되지 않는 것 같다. 실험은 아래와 같이 진행했다.


public class Main {
 
    public static void main(String[] args) {
 
 
        String a = "a";
        String b = "b";
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            a+=b;
        }
        long end = System.currentTimeMillis();
        
        System.out.print("String: ");
        System.out.println(end-start);
 
 
        StringBuilder c = new StringBuilder("c");
        String d = "d";
        long start2 = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            c.append(d);
        }
        long end2 = System.currentTimeMillis();
 
        System.out.print("StringBuilder: ");
        System.out.println(end2-start2);
    }
}


String을 반복문 안에서 +=로 더해봤다. 위 코드의 실행결과는 아래와 같다.


1
2
String: 4028
StringBuilder: 2
cs


 성능차이가 2000배 가량 나는 것을 보면, 분명 append()로의 변환이 일어나지 않았다. 정확한 이유는 모르겠지만, 위에서 언급한대로 Runtime 시점에 일어나는 +연산은 append()로 변환하는데 제한이 있는 듯하다. 정리하자면 String의 +연산은 간단한 문자열을 이어붙일 때만 사용하는 것이 좋다.








-끝-





«   2022/01   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
글 보관함
Total
770,906
Today
340
Yesterday
315