[C#] string 과 StringBuilder 사용

|

문자열을 조합하는 경우가 많이 존재합니다.

보통은 아래와 같이 사용을 합니다.


1.string


string은 값타입이 아닌 참조변수 입니다. 즉, 문자열을 조합할때마다 새로운 클래스가 생성이 되고 이전의 데이터는

GB(Gabage Collector)에 의해서 수집이 됩니다.  따라서 문자열을 조합할때마다 부하가 발생합니다.


1
2
3
 //1.문자열 단순 조합
 string Address = "서울특별시" + " 중구" + " 세종대로";
 Console.WriteLine(Address);
cs


여기서는 총 세번의 String 인스턴스가 생성이 되며 2개의 인스턴스는 GB에 의해서 언제가 될지는 모르지만 수집이 됩니다.

따라서, 메모리 낭비가 발생이 되며 비효율적인 코드가 생산이 됩니다.



2.Stringbuilder


stringbuilder를 사용하면 문자열을 조합할때마다 새로운 변수를 생성하지 않고 결합할 수 있다.

내부에 함수가 존재해서 값들을 조합하거나 삭제할때에도 새로운 인스턴스가 생성되지 않습니다.


1
2
3
4
5
6
7
//2.StringBuiler사용 문자열 조합
StringBuilder sbAddress = new StringBuilder();
sbAddress.Append("서울특별시");
sbAddress.Append(" 중구");
sbAddress.Append(" 세종대로");
                
Console.WriteLine(sbAddress.ToString());
cs


3.주의


문자열을 조합할 때마다 무조건적으로 StringBuilder를 사용하면 안됩니다. 각각의 장단점들이 있기때문에 아래의 조건에 따라서

String을 사용할지 StringBuilder를 사용할지 결정해야합니다.


  3-1 String 클래스를 사용하는 경우 


   -문자열을 수정하는 수가 적을 경우(stringbuilder는 string에 비해서 무시해도 좋을 수준의 성능향상을 제공하거나 전혀 제공하지 않을 수 있음)

   -부분적인 문자열 글자로 고정된 수의 문자열 연결 작업을 할때(컴파일러가 연결 작업을 단일 작업으로 결합할 수 있음)

   -문자열을 작성하는 동안 광법위한 검색 작업을 수행할 때(StringBuilder 클래스는 IndexOf 또는 StartsWith같은 함수가 없다)


 3-2 StringBuiler 클래스를 사용 하는 경우


   -응용 프로그램이 설계시에는 알 수 없는 횟수의 문자열을 변경해야 할 때 ( 사용자의 입력등으로 조합할때 )

   -문자열에서 많은 횟수의 변경이 예상될때



And

[C#] 박싱 과 언박싱 (Boxing & UnBoxing)

|

일반적인 프로그램을 만들면 이 개념에 대해서 몰라도 개발은 가능합니다.

그러나 사용되는 메모리가 많거나 관리가 필요하다면 필수적으로 알아야할 내용입니다.



1.박싱(Boxing)


값타입을 Object 형식 또는 이 값 형식에서 구현된 임의의 인터페이스 형식으로 변환하는 것을 말합니다.

기존에 저장된 스택영역에서 힙영역에 값형식을 저장합니다.


int i = 123;
// The following line boxes i.
object o = i;


위에서 int의 값형식을 Object라는 참조형식으로 형변환을 시도합니다.  그 목적는 여러가지가 있을 수 있는데,

보통 파라미터로 전달되거나, List<Object> 형식으로 모든 값들을 입력받는 목적으로도 사용될 수 있습니다.

위의 코드는 메모리상에서 아래와 같이 메모리가 할당이 됩니다.




스택영역에 있는 i 값이 o로 변환이 되면서 힙영역에 object 형식으로 선언이 되고, 값이 복사됩니다.

o는 스택영역에 존재하며 boxed된 i의 주소값을 가지고 있습니다.


박싱은 보통 암시적으로 되며, 명시적으로도 가능합니다.



2.언박싱(UnBoxing)


Object 형식에서 값형식으로, 또는 인터페이스 형식에서 해당 인터페이스를 구현하는 값 형식으로 변환하는 것을

말합니다.


int i = 123;      // a value type
object o = i;     // boxing
int j = (int)o;   // unboxing

언박싱 과장은 두가지의 절차를 거칩니다.


1.개체 인스턴스가 지정한 값 형식을 boxing한 값인지 확인

2. 인스턴스의 값을 값 형식 변수에 복사




위의 그림에서 보면, int를 박싱한 o의 객체를 다시 int 타입의 j 값에 넣고 있습니다.


언박싱을 할 때 다른 타입으로 하거나, 해당 타입보다 작은 범위로 변환을 하려면 오류(InvalidCastException)가 발생합니다.

이때는 미리 같은 타입인지를 먼저 확인하는 절차를 거쳐야합니다.

is 연산자를 이용해서 미리 같은 타입인지 확인 후에 캐스팅을 해야 안전합니다.



3. 결론


아래는 MSDN에 나오는 Boxing과 UnBoxing에 대한 성능에대한 설명입니다.


This can take up to 20 times longer than a simple reference assignment. When unboxing, the casting process can take four times as long as an assignment.


-박싱을 하면 단순히 참조에 할당하는 것보다 20배까지 시간이 소모되며, 언박싱은 할당에 4배정도 소모된다.


박싱과 언박싱에는 많은 시간이 소모됩니다. 

되도록이면 제네릭을 사용해서 박싱과 언박싱이 일어나지 않도록 구성을 해야하며, 어쩔 수 없이 사용하려면 그 타입에 맞는

캐스팅을 해서 오류가 없이 처리해야합니다.



And

[C#] 진법 변환 ( 진수 변환 )

|

프로그램에서 우리가 보통 많이 사용하는 진법은 4가지정도 있습니다. 2,8,10,16 입니다.

여기에서 각각 진법간의 변환 방법에대해서 알아 보겠습니다.


우선 진법간의 변환은 10진법을 거쳐야만 합니다. 

즉 2진법에서 16진법으로 갈때는 바로 변환을 하지 못하고 2진법->10진법->16진법 식으로 변환과정을 거쳐야 합니다.


여기서 사용하는 클래스는 Convert 입니다. 

10진법으로 변환 : Convert.ToInt32(string value, int frombase) , frombae에 value의 진법

10진법에서 각 진법으로 변환 : Convert.Tostring(int value, int tobase)  , tobase에 변환하려는 진법


그럼 간단한 예제로 마무리 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//2,8,16진법을 10진법으로 변환
string binaryData = "1101";
string octalData = "15";
string hexData = "D";
 
int resultDecimalData = Convert.ToInt32(binaryData, 2);
Console.WriteLine(resultDecimalData); //13
 
resultDecimalData = Convert.ToInt32(octalData, 8);
Console.WriteLine(resultDecimalData);//13
 
resultDecimalData = Convert.ToInt32(hexData, 16);
Console.WriteLine(resultDecimalData);//13
 
 
//10진법을 2,8,16진법으로 변환
int decimalData = 13;
string resultBinaryData = Convert.ToString(decimalData, 2);
string resultOctData = Convert.ToString(decimalData, 8);
string resultHexData = Convert.ToString(decimalData, 16);
 
Console.WriteLine(resultBinaryData);//1101
Console.WriteLine(resultOctData);//15
Console.WriteLine(resultHexData);//d
 
 
//2진법을 16진법으로 변환
resultDecimalData = Convert.ToInt32(binaryData, 2); //2진법을 10진법으로
resultHexData = Convert.ToString(decimalData, 16); //10진법을 16진법으로
 
Console.WriteLine(resultHexData);//d
resultHexData = decimalData.ToString("X2"); //10진법을 16진법(2자릿수 대문자)으로
Console.WriteLine(resultHexData);//0D
cs

+decimalData.ToString("X2")으로도 16진법으로 바로 변환도 가능합니다. 


And