2009-09-17 4 views
0

나는 ~ ~ I 루프 을 통해 그때 추가의 튜플의 목록에 LINQ 필요가 137,000 레코드를 포함 entites의 목록을 가지고 150000Linq에 - 투 - 객체는

왜 더 오래 걸리면 더 반복됩니까? 다음은 스톱워치에서 나온 것입니다. 발견 : 136770 개 항목이 기준에 부합합니다.

10,000 개의 항목이 처리되었습니다. EllapsedTime : 5473That : 0.0912166666666667 minutes.

20,000 개의 항목이 처리되었습니다. EllapsedTime : 15307That : 0.255116666666667 minutes.

30,000 개의 항목이 처리되었습니다. EllapsedTime : 30065That : 0.501083333333333 분.

50,000 개의 항목이 처리되었습니다. EllapsedTime : 74507Th : 1.24178333333333 분.

75,000 개의 항목이 처리되었습니다. EllapsedTime : 157836 : 2.6306 분.

100,000 건이 처리되었습니다. EllapsedTime : 272495Tun : 4.54158333333333 분.

EllapsedTime : 499663 즉 : 8.32771666666667 분입니다.

이것을 최적화 할 수있는 방법이 있습니까? 이 코드에서

List<Entites> alMatched 
List<Tuple<int, double, int, int>> lsItems = new List<Tuple<int, double, int, int>>(); 
IEnumerable<Tuple<int, double, int, int>> enumThingy = lsItems; 

for (int z = 0; z <= alMatched.Count() - 1;z++) 
      { 
       Entity a = alMatched[z]; 
       var newRepl = enumThingy.Where(d => d.First == a.ID).First(); 
       if (newRepl != null) 
       { 

       } 

       switch (z) 
       { 
        case 10000: 
         Debug.Print("10,000 items processed " + ElapsedTime(sw.ElapsedMilliseconds)); 
         break; 
        case 20000: 
         Debug.Print("20,000 items processed " + ElapsedTime(sw.ElapsedMilliseconds)); 
         break; 
        case 30000: 
         Debug.Print("30,000 items processed " + ElapsedTime(sw.ElapsedMilliseconds)); 
         break; 
        case 50000: 
         Debug.Print("50,000 items processed " + ElapsedTime(sw.ElapsedMilliseconds)); 
         break; 
        case 75000: 
         Debug.Print("75,000 items processed " + ElapsedTime(sw.ElapsedMilliseconds)); 
         break; 
        case 100000: 
         Debug.Print("100,000 items processed " + ElapsedTime(sw.ElapsedMilliseconds)); 
         break; 
       } 

      } 

감사

_Eric

+0

귀하의 항목이있는 체인에 나중에 더 많은 시간이 걸립니다 (또는 전혀없는) 것 "Big O notation"을 읽어야합니다. 그 점을 이해하면 이러한 종류의 분석 결과를 해석하는 방법을 이해하는 데 도움이됩니다. 큰 O 표기법을 이해하면 문제의 크기를 처리 할 수있는 적절한 데이터 구조를 선택할 수 있습니다. –

답변

1

확실히. 대신 목록의 사전을 시도

List<Tuple<int, double, int, int>> lsItems = new List<Tuple<int, double, int, int>>(); 

//should be 

var lsItems = new Dictionary<int, Tuple<int, double, int, int>>(); 

/함께 항목을 참조 :

VAR newRepl = lsItems [a.ID]

+0

예! 감사! 발견 : 136770 개의 조건과 일치하는 항목. 10,000 개의 항목이 처리되었습니다. EllapsedTime : 2974That : 0.0495666666666667 분. 20,000 건이 처리되었습니다. EllapsedTime : 5445That : 0.09075 분. 처리 된 30,000 개의 항목 EllapsedTime : 7911That : 0.13185 분. 처리 된 50,000 개의 항목 EllapsedTime : 12883That : 0.214716666666667 분. 처리 된 75,000 항목 EllapsedTime : 19127That : 0.318783333333333 분. 100,000 건이 처리되었습니다. EllapsedTime : 25280That : 0.421333333333333 분. EllapsedTime : 34449 이것은 0.57415 분입니다. – Eric

2

봐 :

for (int z = 0; z <= alMatched.Count() - 1;z++) 
{ 
    Entity a = alMatched[z]; 
    var newRepl = enumThingy.Where(d => d.First == a.ID).First(); 

이 경우 (그리고 나는 당신의 "진짜"사건을 의심 것)에 enumThingyalMatched 열거 형은 둘 다 같은 순서입니다.

이 때문에 케이스 1에있을 때 enumThingy.Where을 호출하면 첫 번째 반복이 반환됩니다. 케이스 100의 경우, 귀하의 조건에 맞도록 100 회 반복하고 종료합니다. 10000의 경우 10000 회 반복됩니다.

기본적으로 더 멀리 갈수록 더 나 빠지게됩니다. 귀하의 알고리즘은 O (N^2)이지만 LINQ는 동일한 목록을 사용하고 있기 때문에 LINQ가 짧게 절단되어 주문이 어디에서 빨리 "단축"할 수 있도록 도와줍니다.

+2

그래, 질문은 정말 "이 O (n^2) 알고리즘이 마치 O (n^2)처럼 동작하는 것인가? ...;) –

0

속도 향상을 위해 다른 aproaches를 사용할 수 있습니다.

하나는 해시 테이블을 사용하여 항목을 enumThingy에 저장하고 찾고있는 키로 액세스 할 수 있습니다.

또 다른 옵션은 enumthingee를 정렬하고 alMatched 것을 정렬 한 다음 "슬라이딩 aproach"를 사용하여 필요한 모든 항목을 찾는 것입니다.

현재 당신은 열거의 작업, 그리고 당신이 필요로하는 하나를 찾기 위해 모든 항목을 확인해야하고, 그래서