c# List 잔기술들 1
TextBox로 한꺼번에 출력하기
리스트의 아이템들을 TextBox에 출력할 때 한 줄씩 하면 느리다. 아래와 같이 한꺼번에 하면 빠르다.
List<int> List1 = new(); private void Form1_Load(object sender, EventArgs e) { for (int i = 0; i < 1000; i++) { List1.Add(i); } } private void Form1_Click(object sender, EventArgs e) { textBox1.Text = String.Join(Environment.NewLine, List1); }
Environment.NewLine은 “\r\n”이라고 해도 된다. 전자는 후자를 호출하므로 후자가 더 빠르다.
아이템 순서 바꾸기
List에는 move 메떠드가 없다. ObservableCollection에는 move가 있지만 바인딩을 할 게 아니라면 List가 더 빠르므로 굳이 ObservableCollection를 쓸 필요는 없다. 어차피 move도 아래와 같은 방법으로 작동한다. 0 1 2 3 4를 0 1 3 2 4로 바꾸는 예제이다.
class Class1 { public int Int; } private void Form1_Load(object sender, EventArgs e) { List<Class1> class1s = new(); Class1 class1; for (int i = 0; i < 5; i++) { class1 = new(); class1.Int = i; class1s.Add(class1); } class1 = new(); class1 = class1s[2]; class1s.RemoveAt(2); class1s.Insert(3, class1); Text = default; for (int i = 0; i < 5; i++) { Text += class1s[i].Int.ToString() + " "; // 0 1 3 2 4 } }
Queue와의 성능 비교
Queue는 맨 앞의 엘리먼트를 지울 때에만 List보다 빠르다. iterate는 for를 쓸 수 없고 foreach만 써야 해서 List를 for에서 돌리는 거보다 느리다. 첫 엘리먼트나 끝 엘리먼트에 액세스하려면 first, last, peek로 인스턴스를 만든 뒤 이거에 액세스를 해야 해서 역시 List보다 느리다. 엘리먼트를 수정할 수도 없고 임의의 엘리먼트를 인덱스 번호로 액세스하는 것도 List의 엘리먼트를 인덱스 번호로 액세스하는 거보다 느리다.
Dictionary와의 성능 비교
특정 엘리먼트를 찾아야 할 때 딕셔너리가 리스트보다 빠르다는 건 기본적인 내용으로 대부분 알고 있다. 그렇다면 예를 들어 증권회사의 api를 이용하여 코스피와 코스닥의 모든 종목들을 제어할 때 어느 걸 쓰는 게 좋을까? 스팩이나 etf 같은 것들을 빼고 주식들만 추리면 코스피와 코스닥 합해서 현재 2,500개 정도 된다. 이것들을 딕셔너리와 리스트에 담고 종목 코드로 특정 종목을 찾아야 할 때 저 정도의 엘리먼트 개수로도 의미 있는 성능 차이가 있을까? 있다.
2,500개의 엘리먼트들을 담은 딕셔너리와 리스트 속에서 임의의 엘리먼트를 1,000번 찾게 했다. 다섯 번 평균 값은 딕셔너리가 0.0000469이고 리스트가 0.0144956로 전자가 300배 넘게 빨랐다. 증권회사의 api를 가지고 주식 종목들을 제어할 때에는 이렇게 종목 찾는 작업이 수도 없이 일어난다. 리스트는 루프를 돌면서 순서대로 하나씩 찾아 가야 해서 찾을 대상이 앞에 있다면 딕셔너리보다 빠르게 결과를 낼 수 있고 뒤에 있다면 더 느리며 전체적으로는 위와 같이 크게 차이 난다. 그러나 액세스해야 할 대상의 인덱스 번호를 알고 있다면 리스트가 더 빠른데 대부분의 경우 인덱스 번호는 알 수가 없다.
List<int> List1 = new(); Dictionary<int, int> Dictionary1 = new(); private void Form1_Load(object sender, EventArgs e) { for (int i = 0; i < 2500; i++) { List1.Add(i); Dictionary1.Add(i, i); } } private void Form1_Click(object sender, EventArgs e) { int in1t; TimeSpan timeSpan1; TimeSpan timeSpan2; Random random = new(); Stopwatch stopwatch = new(); stopwatch.Start(); for (int i = 0; i < 1000; i++) { for (int j = 0; j < 2500; j++) { if (j == random.Next(2500)) { int1 = List1[j]; break; } } } timeSpan1 = stopwatch.Elapsed; stopwatch.Restart(); for (int i = 0; i < 1000; i++) { int1 = Dictionary1[_Random.Next(2500)]; } timeSpan2 = stopwatch.Elapsed; Text = timeSpan1.ToString() + " " + timeSpan2.ToString(); }