2011-09-06 3 views
3

저는 입력, 명확성 및 간결성을 위해 Linq를 좋아합니다. 그러나 나는 2,000 시간의 요인에 의해 오래된 dataview에 비해 일치하는 레코드를 검색하는 것이 매우 느리다는 것을 알게되었습니다!Linq가 데이터보기에 비해 매우 느린 개체

저는 500,000 개의 파일과 500GB의 데이터를 백업하는 앱을 만들고 있습니다. 백업 세트에 파일 목록을 작성하고 디렉토리의 파일을 이미 백업 된 내용을 기록한 매니페스트 파일과 비교합니다. 이렇게하면 어떤 파일이 변경되어 복사해야하는지 알 수 있습니다.

느린 공정이 하나 :

var matchingMEs = from m in manifest where m.FullName == fi.FullName select m;

여기서 manifest = List<ManifestEntry>ManifestEntry 비교적 간단한 POCO이다.

전체 성능은 초당 17-18 레코드입니다.

내가 DataView를 사용하는 경우 : DataView vueManifest = new DataView(dt, "", "FullName", DataViewRowState.CurrentRows);

다음 루프에서 .FindRows와 일치하는 매니페스트 항목을 찾을 수 :

matchingMEs = vueManifest.FindRows(fi.FullName);

를 ... 그때는군요 초당 약 35,000 개의 파일 처리량!

정상입니까? 나는 Linq가 그런 가격에 온다고 믿을 수 없다. Linq 또는 물건을 느리게하는 물건입니까?

은 (BTW, 나는 List<ManifestEntries>뿐만 아니라 DictionarySortedList를 사용하여 시도하고 그들은 모두 같은 결과에 대해 주었다.)

+0

사전에 잘못된 결과가 나타나는 경우 올바르게 초기화하지 않은 것으로 가정합니다. 해당 코드를 보여주십시오. 덧붙여, 'm.FullName'의 표시를 보여주십시오. 'fi'는 어떤 타입입니까? More :'FindRows'는 일치하는 모든 행을 반환합니다. 이 결과에 대한'foreach' 루프는 검색을하지 않습니다. 이와 대조적으로, LINQ는 지연 실행을 사용하고'foreach' 루프 내에서 검색을 수행합니다. 런타임을 올바르게 비교하려면 LINQ'foreach'와'FindRows' +'foreach' 루프 호출 시간을 비교해야합니다. –

+0

그건 맞지 않아. ManifestEntry 란 무엇입니까? 파일에서로드 중입니까? –

+0

난 당신이 먼저 linq 쿼리를 누른 다음 데이터 grideview 쿼리,이 단계에서 모든 파일로드 그래서 데이터 그리드가 빨리 작동하지만 당신은 다른 결과를 얻을 것이다 실행 경로를 반대로 생각합니다. –

답변

1

귀하의 DataView를이 전체 이름별로 정렬되고, 따라서 FindRows 올바른 레코드로 바로 이동할 수 있습니다 (들), 올바른 쿼리 (들)에 도달 할 때까지 귀하의 linq 쿼리는 목록을 반복해야합니다. 500,000 개의 항목이있는 경우 분명히 눈에 띄게됩니다.

var matchingME = (from m in manifest where m.Key == fi.FullName select m).Single(); 

같은

당신이 사전을 사용으로 전환 할 때 전체 이름은 다음, 고유 가정, 당신이 여전히 유사한 LINQ 쿼리를 사용하여 그것을 통해 반복하는 것으로 의심되는 것, 뭔가 당신이

를 사용한다 반면
+0

전설 @sgmoore! 그것은 (거의) 정확하게'.single()'를 빼먹었습니다. 불행히도 지금은 객체의 코드를 찢어 내고 datatable로 대체했습니다. 나는 파일이 한 번 이상 매니페스트에있을 수 있으므로 사전 솔루션이 작동하지 않는다는 것을 깨달았습니다. 즉, 파일의 사본을 삭제하고 수정 한 경우 FullName은 고유하지 않을 수 있습니다. 그래서 당신의 솔루션으로도 나는 여전히 붙어있을 것입니다. 이것은 여전히 ​​linq를 건조하고 건조한 상태로 유지합니까? – RichieRich

+0

@ 리치 리치 당신은 묻습니다. 글쎄, 나는 linq 객체 구현 방법에 대한 전문가가 아니기 때문에 그 질문에 답할 자격이 없지만이 상황에서는 사용하지 않을 것이다. List 에서 시작한 경우 ToDook (키가 고유 한 경우)을 사용하고 그렇지 않으면 ToLookup을 사용합니다. – sgmoore

관련 문제