[델파이/Delphi] TStringBuilder를 사용하는 이유 & 간단 사용법
델파이는 2009 버전부터 StringBuilder를 공식적으로 지원한다.
(Java의 StringBuilder와 같은 개념)
StringBuilder를 사용하는 이유
Buffer Size
일반적으로, Java 환경에서 StringBuilder를 사용하는 대표적인 이유이다.
아래 Java 코드에서 메모리의 Stack 영역과 Heap 영역의 상태 변화는 다음과 같다.
String temp = "Hello";
그리고 temp 변수에 " World" 라는 String을 이어붙이게 되면,
String temp = "Hello";
temp += " World";
결국 "Hello" 라는 String 객체가 존재하는 Heap 영역은 낭비가 되고, 가비지 콜렉터의 제거 대상이 된다. 결국 프로그램이 조금씩 느려지게 될 것.
그래서, 아래 코드처럼 '+' 반복 연산을 하는 경우에는 String 보다는 StringBuilder를 사용하는 것이, 전체 Buffer size 측면에서 유리하다.
String temp = '';
for (int i=0; i < 100; i++) {
temp += "a";
}
그럼 델파이도 마찬가지인가?
그건... 아직은 잘 모르겠다.
구글링을 좀 해보니, 델파이에서의 StringBuilder는 실제 Appilcation이 동작하면서 차지하는 메모리의 총 용량이 String을 사용했을때와 거의 차이가 없다는 벤치 마크 자료가 꽤 많이 나왔다.
궁금해서 직접 간단하게 App을 만들어서 Memory 사이즈를 비교해 보았는데,
수치가 너무 중구난방으로 튀어서 데이터를 신뢰하기는 좀 어려웠다.
그래서 이 부분은 자료를 더 찾아봐야 할 것 같다.
참조 : https://stackoverflow.com/questions/686413/delphi-stringbuilder
동작 속도
위의 예시와 마찬가지로, '+' 반복 연산을 할 때 동작 속도는 StringBuilder가 항상 빠른 것을 확인해 볼 수 있었다.
- 코드 :
StringBuilder는 'a' 를 10,000,000회 Append() 하고, String은 'a'를 '+' 연산으로 이어붙이고,
각 횟수의 동작 시간을 측정하여 표시한다.
procedure RunningTimeTest;
var
I, Idx :Integer;
StringBuilder :TStringBuilder;
sString :String;
begin
//동작 시간 비교 테스트
Memo1.Lines.Add('1. TStringBuilder');
for idx := 1 to 10 do
begin
StringBuilder := TStringBuilder.Create;
WatchStart;
try
for I := 1 to 10000000 do
begin
StringBuilder.Append('a');
end;
WatchStop;
finally
StringBuilder.Free;
end;
end;
Memo1.Lines.Add('');
Memo1.Lines.Add('2. String');
for idx := 1 to 10 do
begin
sString := '';
WatchStart;
for I := 1 to 10000000 do
begin
sString := sString + 'a';
end;
WatchStop;
end;
end;
* [WatchStart], [WatchStop] 프로시져는 System.Diagnostics 의 TStopWatch를 이용하여 직접 구현한 것임.
- 동작 화면 : (단위 : sec)
동작 시간은 StringBuilder가 전반적으로 더 빠른것을 확인해볼 수 있었다.
유의할 점은, 실제 동작 환경에 따라 String이 더 빠를수도 있다는 것이다.
우선 위의 테스트는 반복횟수가 1천만번이라..
실제 운영상에서 1천만번씩 반복하는 경우가 없다면, 둘의 차이가 유의미할 정도로 나지는 않을 것이다.
그리고 위처럼 'a' 라는 단일 문자에 대한 측정은 StringBuilder가 우세했지만,
문자열이 길어질수록 String이 동작 속도가 빨라진다는 것도 확인해볼 수 있었다.
StringBuilder.Append('asdfasdf');
...
...
sString := sString + 'asdfasdf';
위처럼 'asdfasdf'를 이어붙이도록 코드를 변경하고 테스트 해본 결과,
String이 더 빠르게 동작하는 것을 볼 수 있었다.
결론은.. 딱히 TStringBuilder를 써야만 하는 이유는 찾기가 어려웠다.
Java에서는 메모리와 동작속도 측면에서 StringBuilder가 더 유리한 환경이 명확하다고 배웠고,
리팩터링을 할 때 중요하게 고치는 부분이기도 했는데..
델파이는 두 가지 부분에서 명확하게 String보다 더 나아보이는 점이 없었다.
'Delphi' 카테고리의 다른 글
[델파이/Delphi] 자료구조 - Queue (0) | 2022.01.19 |
---|---|
[델파이/Delphi] 시간 측정 - TStopWatch (0) | 2021.12.14 |
[델파이/Delphi] Generic(제네릭) 간단 사용 예제 (0) | 2021.11.27 |
[델파이/Delphi] TStringList - Delimiter & LineBreak, CommaText 예제 (1) | 2021.11.22 |
[델파이/Delphi] 숫자 or 문자 제거하기 (2) | 2021.11.16 |