C# 문자열 보간법 (String Interpolation) 성능 비교

문자열 보간법




C# 6.0 에서는 문자열을 생성하는 새로운 방법이 나왔습니다. 이전에 변수나 식 결과를 문자열의

중간 또는 끝에 삽입 하려면 + 연산자를 사용하거나 String.format 을 사용하였는데 문자열

보간기능을 사용하려면 문자열 내에 중괄호 { } 부호를 넣고 안에 식을 넣기만 하면 됩니다.



사용 예





const string hi = "안녕하세요";
const string bye = "안녕히가세요";
Point point = new Point(30,50);
string text = $"{hi} {bye} {point.X} {point.Y}"; 
/* 
    안녕하세요 안녕히가세요 30 50
*/

Console.WriteLine("{gender==1?"남자":"여자"} 입니다.");

중괄호내에 표현식을 넣으면 ToString() 결과값으로 대체합니다.

즉 어떠한 값 형식 ( int, float, double, bool , ... )이나 참조 형식을 넣어도 ToString() 으로 대체 되어 출력됩니다.



다른 방법과 성능 비교




using System;
using System.Diagnostics;

class Program
{ 
	static void Main()
	{
		int loopCount = 10000000;

		long first = 50002030223;
		string second = "abcdefghijklmnopqrstuvwxyz";
		
		// 문자열 연결
		var stopWatch = Stopwatch.StartNew(); 

		for(int i = 0; i < loopCount; i++)
		{
			string result = first + " - " + second;
		} 
		stopWatch.Stop();

		Console.WriteLine(stopWatch.Elapsed.TotalMilliseconds);

		// 문자열 보간 String Interpolation 
		stopWatch = Stopwatch.StartNew();

		for (int i = 0; i < loopCount; i++)
		{
			string result = $"{first} - {second}";
		}
		stopWatch.Stop();

		Console.WriteLine(stopWatch.Elapsed.TotalMilliseconds); 

		// 복합 형식 지정 Format 
		stopWatch = Stopwatch.StartNew();

		for (int i = 0; i < loopCount; i++)
		{
			string result = string.Format("{0} - {1}", first, second);
		}
		stopWatch.Stop();

		Console.WriteLine(stopWatch.Elapsed.TotalMilliseconds); 
	}
}


Output

 

//1천만 회 돌렸을때 걸리는 계산 시간
1527.379 // 문자열 이어 붙이기
2075.5812 // 문자열 보간 
2092.5805 // format

문자열을 이어 붙이는 방법이 가장 처리가 빨랐고 문자열 보간과 format은 비슷하게 나왔습니다.



C# 박싱 / 언박싱 ( Boxing / Unboxing)


박싱




값 형식 - > 참조 형식


C# 에서 모든 형식(Type)들은 Object를 상속 받습니다. 그 중에 값 형식(Value Type)을 Object로 변환하는

과정을 박싱(Boxing)이라고 합니다. 박싱을 하게 되면 힙(Heap) 영역에 새로운 메모리가 할당되고 값 형식의

값은 새로 할당된 메모리 위치로 복사 됩니다.




언박싱




참조 형식 - > 값 형식


언박싱은 박싱의 역순 입니다. 언박싱(Unboxing) 변환은 박싱된 값 형식이 해당 값을 언박싱 하려는 형식과 호환되는지

형식검사를 한 후에 값 형식 변수에 복사합니다. 언박싱을할 때 박싱할 때 와 다른 타입으로 시도하면

InvalidCastException 런타임 에러가 Throw 됩니다. 언박싱전에 is 연산자를 이용하여 형식을 검사하여 사용하면 됩니다.




박싱 언박싱 변환 동작





1. 힙 영역에 새로운 메모리가 할당되고 할당된 메모리 위치에 a 값을 복사합니다. ( 할당과 복사 )


2. b 는 새로 할당된 a의 사본값을 참조 합니다.


3. 참조 형식 - > 값 형식에 대한 변환을 언박싱이라고 하며 박싱 하기전 형식과 일치하는지 형식 검사를 한 후에 값이 복사된다.



종이에 적힌 값에 비유하면 값을 박싱할 때는 종이를 복사해서 박스에 그 복사본을 넣는 것과 같습니다.

그리고 언박싱할 때는 박스에서 그 종이의 사본을 만드는 것입니다.


힙에 새로운 개체 할당이 일어나는 박싱, 언박싱 연산의 특성 때문에 빈번하게 사용할 경우 리소스를 많이 잡아 먹습니다.

제네릭을 사용하여 해결할 수 있습니다.





C# Invoke를 사용해 크로스 스레드 문제를 해결하는 방법


문제 원인




동시성이 있는 멀티 스레드 프로그램 환경에서  특정 스레드에서 생성된  Win Form 컨트롤 ( TextBox, ListView, Label, … ) 

다른 스레드에서 접근할 발생한다. 스레드에서 안전한 방식으로 컨트롤에 접근 하려면 

컨트롤을 생성한 스레드가 아닌 다른 스레드에서 윈 폼 컨트롤에 접근해야 할 때 적절한 방법으로 스레드 문제를 해결해야 한다.





해결방법




크로스 스레드 문제를 해결하는 방법은 Invoke 메소드를 사용하는 방법과 BackgroundWorker 사용하는 방법이 있다.





Invoke 구현




컨트롤에 접근하고자 하는 스레드에서 InvokeRequired 멤버 값을 가져온다.
True를 반환하면 Invoke 메소드 호출을 필요로 하는 상태고
False를 반환하면 컨트롤에 직접 접근해도 문제가 없는 상태다.


처리량이 적을경우 대리자를 따로 만들지 않고 MethodInvoke와 익명메소드를 사용하면 간결하게 코드를 작성할 수 있다.



public partial class Form1 : Form
{ 
    public Form1()
    {
        InitializeComponent();
        
        // Main 스레드 에서 생성된 컨트롤에 접근 할 또 다른 스레드 
        Thread thread = new Thread(new ThreadStart(CustomThread));
        thread.Start();
    }
    public void CustomThread()
    {
        for(int i=0; ; i++ )
        { 
            // 생성된 스레드가 아닌 다른 스레드에서 호출될 경우 true를 반환하고 정상적인 경우엔 false를 반환한다.
            if(this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate() 
                           { 
                               label1.Text = i.ToString(); 
                           })); 
            } 
            else
            {
                labe1l.Text = i.ToString();
            }
        }
    }
} 



+ Recent posts