* string vs StringBuilder

 

- 기본 비교

 

string 클래스는 값 타입처럼 동작하는 불변 참조 타입이다. 한번 생성되면 수정할 수 없다. 따라서 string에서의 수정은 새로운 string 객체를 할당해서 새로운 string 객체를 참조하는 방법을 사용한다.

 

StringBuilder는 가변 참조 타입이다. StringBuilder에서는 필요한 경우 더 많은 문자를 저장하도록 확장할 수 있다. string 클래스와 다르게 StringBuilder에서의 수정은 새로운 StringBuilder 객체를 생성하지 않고 기존 객체를 확장한다.

 

 

- 사용처

 

일정하게 문자열이 유지되는 경우에는 string 객체를 사용하고 문자열 수정이 많을 것이라고 예측되는 경우 StringBuilder를 사용한다. string과 StringBuilder의 문자열 수정 관련해서 성능 분석한 자료를 보면 성능 차이가 크게 나는 것을 볼 수 있다.

 

https://www.infoworld.com/article/3616600/when-to-use-string-vs-stringbuilder-in-net-core.html

 

When to use String vs. StringBuilder in .NET Core

Take advantage of these best practices when working with strings in .NET Core for the optimal performance of your applications.

www.infoworld.com

 

https://www.c-sharpcorner.com/UploadFile/41e70f/performance-analysis-for-string-and-stringbuilder/

 

Performance Analysis For String and StringBuilder

This article will give you an overview of when and how to use the String and StringBuilder classes with proper statistical data using the CLR Profiler.

www.c-sharpcorner.com

 

 

- string(불변 문자열)이 필요한 이유(Java 기준으로 설명)

 

근데 어차피 변경되지 않을거면 그냥 StringBuilder를 사용해도 되지 않을까? 그냥 전부 다 StringBuilder로 쓰지 왜 굳이 불변 참조 타입인 string 클래스를 따로 만들었을까?

 

1. 문자열 풀(String Pool)

 

불변 문자열 string은 변경되지 않기 때문에 문자열 리터럴을 캐싱하고 재사용하면 많은 힙 공간이 절약된다.

"hello"라는 문자열이 있다고 가정했을 때 해당 문자열을 가지는 string 객체들은 String Pool에서 동일한 객체를 참조한다.

 

Java의 String Pool은 JVM에 의해 문자열들이 저장되는 특별한 메모리 공간이다. 이 문자열들은 변경할 수 없기 때문에 JVM은 각 리터럴 문자열의 복사본을 하나만 저장하여 메모리를 최적화한다. 이를 Interning이라고 한다.

 

s1과 s2는 String Pool에서 동일한 객체를 참조하는 것을 볼 수 있다.

 

C#에서 BenchmarkDotNet을 통해 같은 문자열을 다룰 때와 다른 문자열을 다룰 때 성능 분석을 간단히 해보았다. 정확한 환경에서 테스트한 것은 아니지만 메모리 차이를 확인할 수 있었다.

 

 

2. 보안

 

string을 통해서 로그인 정보, 네트워크 연결과 같은 민감한 정보를 다룰 때 좋다.

 

다음과 같은 함수를 생각해보면

void criticalMethod(string userName) 
{
    // 보안 검사
	
    // string이 변경될 수 있다면 보안 검사 이후에도 언제든지 변경할 수 있기 때문에 보안에 취약하다. 
    // 다른 스레드에서 userName에 대한 참조를 가지고 있으면 다른 스레드에서도 변경될 수 있다.
    
    // 중요 처리 
}

 

 

만약 string이 변경될 수 있다면 보안 검사 이후에도 언제든지 변경할 수 있기 때문에 보안에 취약하다.

또한 다른 스레드에서 userName에 대한 참조를 가지고 있으면 다른 스레드에서도 변경될 수 있다.

 

하지만 string이 불변성 덕분에 안전성을 보장할 수 있다.

 

 

3.  동기화

 

string이 불변이기 때문에 여러 스레드에서 액세스할 때 변경되지 않음을 보장할 수 있다. 변경될 때 문자열을 변경하는 것이 아니라 문자열 풀에 생성되기 때문에 안전하다.(thread safe)

 

 

4.  해시코드 캐싱

 

불병성은 문자열이 변하지 않는다고 가정해주기 때문에 해시 코드를 계산하는 함수에서 첫 번째 호출에서만 해시가 계산되고 그 이후에는 캐시된 동일한 해시코드를 반환한다.

 

 

< 결론 >

 

문자열 풀을 활용하여 재사용으로 힙 메모리를 절약하고, 해시에 대한 성능을 높였으며, 불변성으로 외부에서 변경되지 않음을 보장해준다.

 

 

[참고한 링크] Java에도 불변 문자열 클래스가 존재하는데 그 이유에 대해 다룬 링크이다. 자세하게 설명하고 있다.

https://www.baeldung.com/java-string-immutable

 

Why String is Immutable in Java? | Baeldung

Explore why Strings in the Java language are immutable.

www.baeldung.com

 

'C#' 카테고리의 다른 글

[C#] 박싱과 언박싱(Boxing and Unboxing)  (0) 2022.06.28
[C#] object  (0) 2022.06.28
[C#] Nullable 타입  (0) 2022.06.28
[C#] 값 타입과 참조 타입(Value type, Reference type)  (0) 2022.06.28
[C#] .NET  (0) 2022.06.28

+ Recent posts