StringBuilder는 어떻게 동작할까? (1)

마수리·2024년 7월 21일
0

StringBuilder

목록 보기
1/5
post-thumbnail

안녕하세요. 마수리입니다.

오늘은 StringBuidler에 대해서 알아볼까 합니다.

이 주제를 선택한 이유는 2가지가 있는데요

  1. 면접에 자주 등장한다.
  2. 사용시 반드시 알아야할 문제(?)가 있다. (StringBuilder도 만능은 아님 😁)

오늘의 글에선 StringBuilder에 대해 간단한 개요를 이야기 해볼까 합니다.

여러분도 기본적으로 다들 알고 계신 것은 C#이나 JAVA의 string 객체는 불변타입이라 + 연산 등으로 string을 이어 붙인다면 계속해서 새로운 string 객체가 생성되어 메모리 낭비와 GC의 부담을 준다는 것입니다. 이런 것을 해결하기 위해 등장한 것이 바로! 오늘의 주인공! Stringbuilder입니다!

StringBuilderAppend(), AppendLine()등의 함수를 이용해서 추가적인 메모리 할당 없이(?) String 객체를 조작할 수 있다고 알려져 있는데요. StringBuilder는 과연 어떻게 이루어져 있을까요?

한번 진지하게 고민해보시면 좋을 것 같습니다. 왜냐구요? 누군가 면접에서 물어보거든요 😂
다행히 저는 그때 당시 내가 StringBuilder의 개발을 맡았다면 이렇게 했을 것이다 라고 잘 추측해서 이야길 했고 대부분 실제 코드도 그러 하였습니다. 여러분도 지금 이 글을 더 읽기 전에 한번 쯤 고민해 보셨으면 합니다

과연 StringBudiler는 어떻게 문제를 해결했을까?

우선 가장 먼저 떠올리셔야 하는 아이디어는 버퍼입니다.
StringBuilder는 지속적인 메모리 할당을 피하기 위해 자체 버퍼를 가지고 있습니다. 계속적인 string객체의 메모리 할당을 피하기 위해선 자체 버퍼를 가지고 있어 한번만 크게 메모리를 할당하고 그 할당된 공간에 문자열을 추가하는 방식으로 구현되어 있을 것입니다.

그럼 다음 고민이 버퍼의 크기를 어떻게 결정하냐는 것이다.
버퍼의 크기는 기본 생성자를 호출했을 때 16개의 문자를 받을 수 있게 설정 되어있습니다. 그럼 StringBuilder는 16개의 문자만 받을 수 있는건가? 그렇지 않습니다. 만약 16개 이상의 문자를 Append()한다면 기존 버퍼들(최종적으로 버퍼는 여러개가 될 수 있습니다)의 크기에 비례해 새로운 버퍼를 만들고 문자열을 계속 이어서 버퍼에 써 내려갑니다.

어려분이 Append() 혹은 AppendLine()을 사용해서 문자열을 이어나간 이유는 최종적으로 ToString()을 사용해서 string객체를 얻기 위함이였을 것입니다. 그럼 ToString()을 했을 땐 어떻게 최종적으로 string객체를 만들어 줄까요?

string객체를 기존에 가지고 있던 모든 버퍼의 크기를 합한 것만큼 한번에 할당하고 기존에 있던 모든 버퍼를 돌면서 복사를 진행합니다. 이렇게 되면 적어도 + 연산을 이용해서 계속해서 메모리를 할당하는 것에 비해선 확실히 메모리 할당과 GC의 부담을 줄여줄 것 같습니다.

우리가 사용하던 StringBuilder는 이러한 과정을 통해서 작업이 이루어집니다.

그럼 StringBuilder를 어떻게 사용해야 좋을까요? 내부 구현은 어떻게 되어있을까요?

그 이야기에 대해선 다음 글에서 이야기 해보도록 하겠습니다.

감사합니다.

profile
.NET 개발자 마수리입니다 🖐

0개의 댓글