대용량 자료구조를 검색할 일이 생기다보면
종종사용하게되는 함수가 Find, FirstOrDefault 인데..
이것이들 내부적으로는 다르게 돌아가서 속도 차이가 난다고한다.
실제로 얼마나 차이가 나는지 간단한 코드로 테스트해보았다.
테스트 환경
CPU : Intel i5-9600K 3.7GHz
운영체제 : 윈도우 10 64비트
컴파일러 : Visual Studio 2019 Community
검색 개수 : 30,000,000 (3천만개)
검색 조건 : 제일 마지막 데이터 검색
첫번째 케이스 : Find 10회 결과(ms)
RunTime1 : 438 ms
RunTime1 : 438 ms
RunTime1 : 424 ms
RunTime1 : 434 ms
RunTime1 : 427 ms
RunTime1 : 431 ms
RunTime1 : 424 ms
RunTime1 : 425 ms
RunTime1 : 431 ms
RunTime1 : 432 ms
RunTime1 Average : 430.4 ms
두번째케이스 : FirstOrDefault 10회 결과(ms)
RunTime2 : 625 ms
RunTime2 : 583 ms
RunTime2 : 578 ms
RunTime2 : 579 ms
RunTime2 : 580 ms
RunTime2 : 581 ms
RunTime2 : 581 ms
RunTime2 : 587 ms
RunTime2 : 579 ms
RunTime2 : 583 ms
RunTime2 Average : 585.6 ms
세번째케이스 : Where + FirstOrDefault 10회 결과(ms)
RunTime3 : 525 ms
RunTime3 : 516 ms
RunTime3 : 514 ms
RunTime3 : 508 ms
RunTime3 : 530 ms
RunTime3 : 515 ms
RunTime3 : 512 ms
RunTime3 : 512 ms
RunTime3 : 521 ms
RunTime3 : 516 ms
RunTime3 Average : 516.9 ms
네번째케이스 : for loop 10회 결과(ms)
RunTime4 : 424 ms
RunTime4 : 403 ms
RunTime4 : 407 ms
RunTime4 : 406 ms
RunTime4 : 402 ms
RunTime4 : 405 ms
RunTime4 : 411 ms
RunTime4 : 403 ms
RunTime4 : 411 ms
RunTime4 : 410 ms
RunTime4 Average : 408.2 ms
결과
for loop(408.2 ms) > Find(430.4 ms) > Where + FirstOrDefault(516.9 ms) > FirstOrDefault(585.6 ms)
테스트 코드
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ListSearchSpeedTest { public partial class Form1 : Form { List<UserData> listUserData = new List<UserData>(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { for (int i = 0; i <= 30000000; i++) { listUserData.Add( new UserData { ID = i.ToString(), Name = i + "th Junior" } ); } } private void button1_Click(object sender, EventArgs e) { List<long> listResult = new List<long>(); Stopwatch stopWatch = new Stopwatch(); for (int i = 0; i < 10; i++) { stopWatch.Restart(); UserData item = listUserData.Find(x => x.ID == "30000000"); stopWatch.Stop(); listResult.Add(stopWatch.ElapsedMilliseconds); Console.WriteLine("RunTime1 : " + stopWatch.ElapsedMilliseconds + " ms"); } Console.WriteLine("RunTime1 Average : " + listResult.Average() + " ms"); } private void button2_Click(object sender, EventArgs e) { List<long> listResult = new List<long>(); Stopwatch stopWatch = new Stopwatch(); for (int i = 0; i < 10; i++) { stopWatch.Restart(); UserData item = listUserData.FirstOrDefault(x => x.ID == "30000000"); stopWatch.Stop(); listResult.Add(stopWatch.ElapsedMilliseconds); Console.WriteLine("RunTime2 : " + stopWatch.ElapsedMilliseconds + " ms"); } Console.WriteLine("RunTime2 Average : " + listResult.Average() + " ms"); } private void button3_Click(object sender, EventArgs e) { List<long> listResult = new List<long>(); Stopwatch stopWatch = new Stopwatch(); for (int i = 0; i < 10; i++) { stopWatch.Restart(); UserData item = listUserData.Where(x => x.ID == "30000000").FirstOrDefault(); stopWatch.Stop(); listResult.Add(stopWatch.ElapsedMilliseconds); Console.WriteLine("RunTime3 : " + stopWatch.ElapsedMilliseconds + " ms"); } Console.WriteLine("RunTime3 Average : " + listResult.Average() + " ms"); } private void button4_Click(object sender, EventArgs e) { List<long> listResult = new List<long>(); Stopwatch stopWatch = new Stopwatch(); for (int i = 0; i < 10; i++) { stopWatch.Restart(); for (int j = 0; j <= 30000000; j++) { if (listUserData[j].ID == "30000000") break; } stopWatch.Stop(); listResult.Add(stopWatch.ElapsedMilliseconds); Console.WriteLine("RunTime4 : " + stopWatch.ElapsedMilliseconds + " ms"); } Console.WriteLine("RunTime4 Average : " + listResult.Average() + " ms"); } } public class UserData { public string ID { get; set; } public string Name { get; set; } } } | cs |