[유니티/C#] StringBuilder 정리 및 사용법
글 작성자: Coding Groot
C# 공식 문서에 잘 정리되어있지만 필요할 때마다 코드를 찾아보기가 귀찮고 기계 번역된 한국어 문서는 너무 어색해서 영어로 봐야 하는 번거로움이 있어서 정리할 겸 쓰는 글이다.
문제
자바든 C#이든 String을 짧은 시간 동안 (예를 들어서 반복문) 계속 수정(Concat)해주면 계속 동적 활당을 해서 성능이 크게 저하가 될 수 있다.
문제가 되는 코드 예시
using System; public class Program { string BadCodeExample() { string myString = ""; for (int i = 0; i<20; i++) { myString += i.ToString() + ", "; } myString = myString.Remove(myString.Length - 2); // 뒤에 남은 ", " 제거 return myString; } }
이유
String
은 변경할 수 없는 형식이다.
String의 문자열을 변경을 하면 변경된 문자열을 위한 새로운 String을 만들어 낸다.
그래서 반복문같은 곳에서 계속 String을 변경하면 성능 저하가 일어날 수 있다.
해결법
StringBuilder
는 변경 가능한 문자열 Class이다.
StringBuilder를 사용하면 해결된다. StringBuilder는 바로 아래의 예시를 보면 어떻게 사용하는지 이해가 될 것이다.
위에서 문제가 됐던 코드를 StringBuilder를 사용하는 코드로 수정해보겠다.
StringBuilder를 사용해서 성능 저하를 줄인 예시
using System.Text; // StringBuilder 쓰기 위함 using UnityEngine; public class SBTestScript : Monobehaviour { string StringBuilderExample() { StringBuilder sb = new StringBuilder(); // Append for (int i = 0; i<20; i++) { sb.Append(i).Append(", "); } return builder.ToString(); } void Start() { Debug.Log(StringBuilderExample()); } }
더 상세하게 알아보자.
StringBuilder 생성자
- StringBuilder(): 새로운 StringBuilder 인스턴스 초기화
- StringBuilder(int): 새로운 StringBuider 인스턴스를 지정된 용량(Capacity)을 사용해서 초기화
- StringBuilder(string): 새로운 StringBuilder 인스턴스를 지정해준 문자열을 사용해서 초기화
- StringBuilder(string, int): 새로운 StringBuilder 인스턴스를 지정해준 문자열과 용량을 사용해서 초기화
- ... 최대 용량도 지정해줄 수 있다. 나머진 공식문서를 참고하자.
StringBuilder의 매서드들을 사용해보자.
using System.Text; // StringBuilder 쓰기 위함 using UnityEngine; public class SBTestScript : Monobehaviour { string StringBuilderExample2() { // 80 character를 가질 StringBuilder 생성 // "숫자 세기 시작: "이라는 문자열로 초기화 StringBuilder sb = new StringBuilder("숫자 세기 시작: ", 80); // 문자의 배열을 StringBuilder 뒤에 Append하기 sb.Append(new char[]{'1', '2', '3', '4', '5', '5'}); // StringBuilder 제일 앞에 문자열 넣기 sb.Insert(0, "[테스트용] "); // StringBuilder안의 모든 '5'를 '6으로 바꾸기' sb.Replace('5', '6'); // StringBuilder안에 있는 문자열의 길이와 문자열 출력하기 Debug.Log("길이: {0}, 문자열 내용: {1}", sb.Length, sb.ToString()); } void Start() { Debug.Log(StringBuilderExample2()); } }
위에 코드에서 사용한 메서드들 말고도 Format을 지정해주는 등 다른 메서드들도 있다. 그 부분이 궁금하다면 C# 공식 문서를 참고하자.
StringBuilder 사용할 때 주의할 점
- StringBuilder 클래스는 IndexOf()나 StartsWith() 같은 검색 메서드가 부족하다. 만약에 검색 메서드가 필요하다면 다시 String으로 변환해서 사용해야 한다. (부분 문자열의 인덱스 검색이 아니라 그저 포함관계만 알고 싶은 경우면 상관없다 - Contain메서드를 사용하면 된다)
- 최대 용량인 StringBuilder.MaxCapacity가 되기 전까지 StringBuilder는 문자열을 담을 용량인 StringBuilder.Capacity가 부족하면 동적 할당을 계속해서 공간을 확보한다.
- 최대 용량을 초과하면 ArgumentOutOfRangeException 또는 OutOfMemoryException 예외가 throw 된다.
- StringBuilder와 String 인스턴스는 모두 UTF-16 인코딩으로 문자를 저장한다.
출처
- 마이크로소프트 공식 문서: https://docs.microsoft.com/ko-kr/dotnet/api/system.text.stringbuilder?view=netframework-4.8
StringBuilder 클래스 (System.Text)
변경할 수 있는 문자열을 나타냅니다.Represents a mutable string of characters.
docs.microsoft.com
- 위의 문서를 읽으려고 한다면 영어로 보는 것을 추천한다. 문서 자체의 내용은 자세하게 잘 설명되어 있지만 한국어 기계 번역이 좀 어색하다.
- Icons made by iconixar from www.flaticon.com
반응형
댓글
이 글 공유하기
다른 글
-
[유니티] SDK 경로 찾기 :: "Unable to detect SDK in the selected directory"
[유니티] SDK 경로 찾기 :: "Unable to detect SDK in the selected directory"
2020.04.12 -
[유니티] 모든 자식들 접근하기
[유니티] 모든 자식들 접근하기
2020.02.26 -
[유니티] Bool 난수 생성하기
[유니티] Bool 난수 생성하기
2020.02.26 -
[유니티] GameObject 없이 코드 실행하기
[유니티] GameObject 없이 코드 실행하기
2019.07.19
댓글을 사용할 수 없습니다.