Written by 안재우(Jaewoo Ahn), 닷넷엑스퍼트(.netXpert)
예전 Voice of .NETXPERT 2003 행사 때, 저희 회사의 김유철 책임이 발표했던 내용인 '아무도 가르쳐 주지 않는 .NET 애플리케이션 개발 Tips 18가지'를 정리해서 올립니다.
두번째로 .NET Framework 관련 팁 2가지입니다.
Tip 4. StringBuilder의 잘못된 사용
문자열(System.String)의 경우, 소위 말하는 Immutable 패턴을 따르고 있기 때문에 독특한 특성을 가지는데, 간략하게 설명하면 다음과 같습니다. 우선 다음 코드를 봅시다.
string s = "Hello";
s = s + ", ";
s = s + "World !";
이렇게 했을 때, 실제 메모리 상에서는 다음과 같이 문자열에 해당하는 메모리 공간이 3번 점유됩니다.
Memory #0 : [Hello]
Memory #1 : [Hello, ]
Memory #2 : [Hello, World!]
즉 동일한 메모리 주소(#0)에 추가되는 것이 아니라, 문자열 연산을 수행한 결과의 문자열이 새로운 메모리 주소에 할당된다는 것입니다.
이에 비해 StringBuilder라는 클래스를 우리가 일반적으로 생각하는 방법처럼 동일 메모리 주소(#0)에 문자열을 추가함으로써 재할당의 오버헤드, 불필요한 메모리 공간의 낭비를 줄입니다. StringBuilder를 사용할 경우, 위 코드는 다음과 같이 됩니다.
StringBuilder sb = new StringBuilder();
sb.Append("Hello");
sb.Append(", ");
sb.Append("World!");
이 때문에 상당수의 .NET 프로그래밍 팁에서는 문자열 연산을 여러번 수행하는 경우, StringBuilder를 사용하면 성능이 좋아진다고 설명해놓은 경우가 많습니다.
문제는 이를 맹신하고 남용하는 사람들이 많다는 것입니다. 실제로 다른 .NET 팁을 보고 나서 무조건 StringBuilder를 사용해서 코드를 작성하는 프로그래머를 본 적도 있습니다. 과연 그게 맞을까요? 위에서 본 두 가지 경우와 아래의 경우 중 성능이 가장 좋은 것은 어느 것일까요?
string s = "Hello" + ", " + "World!";
가장 바람직한 것은 바로 위, 즉 맨 마지막의 경우입니다. 바로 위처럼 작성한 경우, C# 컴파일러는 MSIL을 생성할 때 위 코드를 다음과 같이 최적화합니다.
string s = "Hello, World!";
그러므로 문자열 상수 연산이나 보통 5개 이하의 문자열 연산에는 StringBuilder를 사용하지 말고 + 연산자를 사용하는 것이 바람직합니다. StringBuilder를 써야 할 경우는 다수의 문자열 연산을 수행하거나, 반복문(for, while 루프 등) 내에서 문자열 연산을 수행할 경우입니다.
성능 뿐만 아니라 코드 가독성 측면에서도 + 연산을 사용하는 것이 StringBuilder.Append()를 사용하는 것보다 훨씬 나으므로, 코드 생성기나 HTML 렌더링과 같은 특수한 작업을 수행하지 않는 일반적인 경우라면 + 연산을 사용하는 것을 권장하고 싶습니다.
Tip 5. 콘솔 애플리케이션 출력 캡쳐
요즘은 대부분 웹이나 윈도우 애플리케이션으로 작성하긴 하지만, 간혹 가다 콘솔(커맨드라인) 애플리케이션을 작성해야 할 경우도 있습니다. 이럴 경우, 콘솔 애플리케이션의 출력 내용을 캡쳐하는 방법은 없을까요?
System.Diagnostics.ProcessStartInfo 클래스를 사용하면 이를 간단하게 수행할 수 있습니다. 다음 코드를 보죠.