VisualStudio/C#

[C#] StringBuilder VS StringBuffer

usingsystem 2022. 8. 22. 14:55
728x90

 StringBuilder는 문자열의 저장 및 변경을 위한 메모리 공간을 지닌 클래스이다.

 문자열 데이터의 추가를 위한 append와 중간에 삽입을 위한 insert 메소드를 제공한다.

append는 문자열을 순서대로 저장할 때

insert는 문자열을 중간에 저장할 때

 

 

위의 메소드를 통해 메모리 버퍼에 문자열을 쌓고나서 toString을 이용해 문자열을 만든다.

 기본 16개의 문자저장 메모리 버퍼를 생성한다. 물론 아래와 같이 임의로 지정할 수도 있다.

public StringBuilder(int capacity);     // capacity 만큼의 문자저장 버퍼를 생성

 문자열이 들어간 버퍼를 만들수도 있다.

public StringBuilder(String str);    // 문자를 저장한 문자저장 버퍼를 생성

 

 

 StringBuilder는 무조건 두개의 인스턴스만을 생성한다.

ex. String str4 = 1 + "Lemon" + 2;

new StringBuilder().append(1).append("Lemon").append(2).toString();

new StringBuilder() 하나, toString 하나해서 2개의 인스턴스만을 생성 ->??

 

 

StringBuffer는 멀티쓰레드에 안전(thread safe)하도록 동기화 되어 있다. 아직은 멀티쓰레드나 동기화에 대해서 배우지 않았지만, 동기화가 StringBuffer의 성능을 떨어뜨린다는 것만 이해하면 된다. 멀티쓰레드로 작성된 프로그램이 아닌 경우, StringBuffer의 동기화는 불필요하게 성능만 떨어뜨리게 된다. 그래서 StringBuffer에서 쓰레드 동기화만 뺀 StringBuilder가 새로 추가되었다.

StringBuilder는 StringBuffer와 완전히 똑같은 기능으로 작성되어 있어서 소스코드에서 StringBuffer대신에 StringBuilder로 바꾸기만 하면 된다. 즉, StringBuffer타입의 참조변수를 선언한 부분과 StringBuffer의 생성자만 바꾸면 된다.

StringBuffer도 충분히 성능이 좋기 때문에 성능향상이 반드시 필요한 경우를 제외하고 StringBuffer를 StringBuilder로 바꿀 필요가 없다.

 

String

-  짧은 문자열을 더할 경우 사용

 

StringBuilder 

단일 스레드에서 안전성만을 보장한다.

- 스레드에 안전여부에 전혀 관계 없는 프로그램을 개발할 때 사용하면 좋음

- 메서드 내에 변수를 선언했다면, 해당 변수는 그 메서드 내에서만 살아있으므로 이 클래스를 사용해야함

 

StringBuffer

- 스레드에 안전하게 설계되어 있으므로, 여러 개의 스레드에서 하나의 StringBUffer 객체를 처리해도 전혀 문제가 되지 않는다.

- 개발 중인 시스템이 스레드에 안전한지 모를경우 사용하면 좋음

- 클래스에 static으로 선언한 문자열을 변경하거나, singleton 으로 선언된 클래스에 선언된 문자열일 경우 이 클래스를 사용해야함

 

응답시간

String > StringBuffer > StringBuilder

 

메모리

String >StringBuffer == StringBuilder



출처: https://clairdelunes.tistory.com/46 [거꾸로 바라본 세상]

 

String클래스는 불변 객체이기 때문에 문자열 연산이 많은 프로그래밍이 필요할 때 계속해서 인스턴스를 생성하므로 성능이 떨어지지만 조회가 많은 환경, 멀티쓰레드 환경에서 성능적으로 유리합니다.

StringBuffer클래스와 StringBuilder클래스는 문자열 연산이 자주 발생할 때 문자열이 변경가능한 객체기 때문에 성능적으로 유리합니다.

StringBuffer와 StringBuilder의 차이점은 동기화지원의 유무이고 동기화를 고려하지 않는 환경에서 StringBuilder가 성능이 더 좋고, 동기화가 필요한 멀티쓰레드 환경에서는 StringBuffer를 사용하는 것이 유리합니다.

* StringBuffer와 StringBuilder는 성능으로 따졌을 때 2배의 속도차이가 있다고 하지만 참고사이트의 속도 차이 실험 결과 append()연산이 약 1억6천만번 일어날 때 약 2.6초의 속도차이를 보인다고 합니다.

(String은 +연산이 16만번이상 넘어가게 되면 10초이상 걸리면서 못 쓸정도의 성능을 보입니다.)

따라서 문자열연산이 많지만 엄청나게 일어나지 않는 환경이라면 StringBuffer를 사용해서 thread-safe한 것이 좋다는 생각입니다.

* JDK1.5이상부터 String에서 +연산으로 작성하더라도 StringBuilder로 컴파일하게 만들어 놨다지만 여전히 String클래스의 객체 생성하는 부분을 동일하므로 StringBuffer,StringBuilder 사용이 필요함.

+ StringBuffer, StringBuilder의 경우 buffer size를 초기에 설정해야하는데 이런 생성, 확장 오버로드가 걸려 버퍼사이즈를 잘못 초기화할 경우 성능이 좋지 않을 수 있음.

+ String클래스가 컴파일러분석단계에서 최적화될 가능성이 있기때문에 간혹 성능이 잘나오는 경우도 있음. 문자열 연산이 많지 않은 경우는 그냥 사용해도 무방.

런타임에서 문자열조합이 많아질 경우 String은 여전히 성능이 아주 안좋기 때문에!

+, concat을 사용하는 사고(?)를 치면 안된다. 특히 현업에서....



출처: https://jeong-pro.tistory.com/85 [기본기를 쌓는 정아마추어 코딩블로그]

 

String a = "hello";
String a2 = "hello";

System.out.println(a);
System.out.println(a.concat(" world"));
System.out.println(a); //그대로 hello출력


//그냥 String클래스보다 성능면에서 더 좋다. 메모리 할당과 메모리 해제를 발생 시키며 더하는 연산이 많아진다면 성능적으로 좋지 않다.
//StringBuilder는 String문자열을 더할 때 새로운 객체를 생성하는 것이 아니라
// 기존의 데이터에 더하는 방식을 사용하기 때문에 속도도 빠르며 상대적으로 부하가 적다. 현업에서는 sb.concat안됨
StringBuilder sb = new StringBuilder();
sb.append("hello");
sb.append(" world");
System.out.println(sb.toString());

 

System.out.println("start");
String str = "";
for (int i = 0 ; i < 1000000; i++) {
    str += i;
    sb.append(i); //for문안에선 stringbuilder가 빠르지만 string은 느리다... 100000을 돌려 봤을때
}
System.out.println("end");

 

StringBuffer클래스와 StringBuilder 클래스의 공통점

 

-> 메소드의 수(생성자 포함)

-> 메소드의 기능

-> 메소드의 이름과 매개변수 형

 

StringBuilder클래스를 StringBuffer클래스로 변경하여도 컴파일 및 실행이 정상적으로 됩니다.

 

StringBuffer클래스와 StringBuilder클래스의 차이점

StringBuffer는 쓰레드에 안전,

StringBuilder는 쓰레드에 불안정

 

출처 - https://aomee0880.tistory.com/150

728x90