반응형

 

문자열을 사용하다 보면,

예제로 자주 등장하는 StringBuilder 클래스를 한 번쯤은 봤을 것이다.

그리고 그 것을 응용해서 우리가 프로그래밍을 하면서도 사용해 봤을 것이다.

 

나도 그렇지만 다른 개발자들도

왜 해당 클래스를 많이 사용하는지에 대한 생각을 안 해봤을 것이다. (해봤으면 죄송합니다.)

 

StringBuilder를 적극적으로 사용해야 하는 이유에 대해 알게 되어서 공유해보려고 한다.

예제를 보면서 살펴보자.

1
2
var text = "Hello World";
var textLower = text.ToLower();
cs

우리가 자주 사용하는 문자열 메서드들 중에서,

ToLower(모든 문자를 소문자로) 메서드를 사용해서 변수에 넣는다고 생각해보자.

 

첫 번째 라인에서, text변수는 힙에 있는 "Hello World"를 가리키게 될 것이다.

두 번째 라인에서, ToLower메서드를 호출하면서 text 변수에 담긴 문자열이 소문자로 변경되는 것이 아니라 원문이 통째로 복사된 다음 그것이 소문자로 변경되어 반환되는 절차를 걸친다.

 

조금 헷갈리는 분들이 있을 것 같아 다른 예제를 만들어보자.(안 헷갈렸으면 다시 한번 죄송합니다.)

모니모니해도 걸리는 시간 테스트해보면 왜 StringBuilder를 사용해야 하는지 알 수 있을 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var text = "Hello World";
 
var start = DateTime.Now;
for (var i = 0; i < 500000; i++) {
    text = text + "a";
}
var end = DateTime.Now;
Console.WriteLine($"StringBuilder 사용 x : {end - start}");
 
 
start = DateTime.Now;
var sb = new StringBuilder();
sb.Append(text);
for (var i = 0; i < 500000; i++) {
    sb.Append("a");
}
end = DateTime.Now;
Console.WriteLine($"StringBuilder 사용 o : {end - start}");
cs

결과는 위에와 같다.

StringBuilder를 사용 안 했을 때에는 1분이 넘게 걸렸고,

StringBuilder를 사용했을 때에는 0초였다. 결과는 완벽하게 StringBuilder의 승리이다.

 

그럼 왜 이렇게 StringBuilder가 빠를까?

첫 번째 예제에서는 메모리의 할당과 복사가 지속적으로 이루어졌다.

5번째 라인에서 text값과 a라는 문자열을 합친 값을 복사,

그리고 그 값의 길이만큼 공간을 힙에 할당하고 text변수가 가리키는 값이 바뀌게 된다.

이러한 작업이 50만번 이루어지는 것이다.

 

하지만 StringBuilder는 내부적으로 일정한 양의 메모리를 할당한다.

그리고 Append 했을 때에 그 값이 메모리에 복사된다.

할당된 메모리가 모두 사용했을 때에, 그때 새롭게 여유분의 메모리를 추가로 할당하기 때문이다.

즉, 첫 번째와 달리 잦은 메모리 할당과 복사가 없어졌기 때문에 그만큼 성능이 향상되었던 것이다.

문자열을 연결하는 작업이 있으면, 꼭꼭 StringBuilder를 사용하자.

 

반응형

+ Recent posts