2012-06-20 2 views
3

내 문제의 일부 기사를 찾으려고했지만 관련성이 있거나 내 응용 프로그램에 적합한 내용을 찾지 못했습니다. 여기에 내 문제가 있습니다 :C# 대용량 데이터 목록을 신속하게 처리하는 방법

(> 20,000) 개의 항목이 두 개 있습니다.

각 목록의 각 항목을 반대 목록의 모든 항목과 대조해야합니다.

이 같은의 구현 :

foreach(var item1 in List1) 
    { 
     foreach(var item2 in List2) 
     { 
       // Check item 1 against item 2. 
       // Check item 2 against item 1. 
     } 
    } 

때문에 확인을 위해 수행 된 작업의 매우 느리고 사용할 수 없습니다.

이렇게 많은 수의 항목을 처리하는 효율적인 방법이 있습니까?

내가 제공 할 수있는 정보가 더 있으면 알려 주시기 바랍니다. 도움/의견을 보내 주셔서 감사합니다.

나는 C# .NET을 3.5

편집을 사용하고 있습니다 : 저를 시도하고 간단한 방법으로 검사를 설명해 보자.

item1과 item2는 경로 지정 시스템의 일부입니다. item1과 item2는 N 개의 다른 항목으로 연결됩니다. item1이 item2에 연결되어 있는지 확인하고 item2가 item1에 연결되어 있는지 확인합니다. item1 -> item2 인 경우 item2 -> item1이라고 가정 할 수 없습니다. 따라서 두 가지 검사가 모두 필요합니다.

데이터베이스에는 item1 -> item2 및 if/how item2 -> item1의 정보가 포함되어 있습니다. 수표 안에는 수표를 보내는 서비스에 대한 명명 된 파이프 호출이 있습니다. 서비스는 모든 경로 검사를 수행하고 item1 -> item2 등을 반환합니다.

+1

데이터의 큰 코퍼스가 있고 믹스에 데이터베이스가있는 경우 모든 데이터를 반복하기 전에 데이터베이스에서 일부 사전 필터링을 수행 할 수 있습니까? – 48klocs

+0

목록에 대한 자세한 정보를 제공해주십시오. 고유 한 값입니까? 그렇다면 해시 세트를 사용해야합니다. 프레임 워크 해시 셋 구현에는 효율적인 세트 비교 연산이 있습니다. –

+0

논리적으로 당신은 일종의 "조인"을하고 있습니다. 그런 식으로 DB에 내장 된 메커니즘 (및 최적화)을 사용하여 구현해야합니다 ... –

답변

1

각 반복에 대한 요청이 데이터베이스로 전달되는 것을 피하십시오. 가능하면 루프 외부에서 하나의 쿼리를 모두 만들거나 루프 외부에서 필요한 데이터를 가져 와서이 데이터를 확인하십시오.

모두는 검사 작업에 따라 다릅니다. 그렇게 설명하십시오. 당신의 반복은 독립적하지만 어쨌든, 당신은 또한 PLINQ 및 작업이 O(N * M) 검사의

Data Parallelism (Task Parallel Library)

Libary

How to: Write a Simple Parallel.ForEach Loop

+0

링크를 제공해 주셔서 감사합니다.이 링크는 .NET 4.0에서만 사용 가능하며 3.5로 제한됩니다. – therealjohn

+0

.NET 3.5를 사용하고 있다는 것을 눈치 채지 못했습니다. .NET 3.5 TPL에서는 사용할 수 없습니다. 그러나 루프 반복을 병렬화 할 수 있습니다. 단일 반복은 오랜 시간이 걸리며 서로 독립적입니다. .NET 3.5 ThreadPool.QueueUserWorkItem을 사용해야하며 모든 반복을 기다리는 동안 Wait 핸들을 사용해야합니다. TPL의 데이터 병렬 처리와 동일하지만 수동으로 작성되었습니다. – Regfor

+0

답장을 보내 주셔서 감사합니다. – therealjohn

2

긴 루프 + 데이터베이스 쿼리 = 끔찍한 성능.

시도해야 할 일은 쿼리를 먼저 실행하고 필요한 데이터를 얻은 다음 해당 데이터에 대해 NxM 검사를 수행하는 것입니다.

물론 이것이 반드시 필요한 것은 아닙니다. 당신이하는 수표의 종류에 달려 있습니다.

+0

내 조건에서는 이것이 가능한지 확실하지 않습니다. 각 항목 1은 경로를 확인하기 위해 수표에서 호출 된 서비스로 이동해야합니다. – therealjohn

3

병렬 사용하여 루프를 병렬화 할 수 있습니다.

일부 키 또는 다른 키의 평등을 비교하는 경우 합리적인 해시 코드 및 올바른 키 분배를 가정하고 O (N + M) 반복을 수행 할 수 있습니다. 이것을하기위한 가장 간단한 방법.당신이 도움이되지 않는 어떤지를 확인 하지라면, 물론

var pairs = from x in List1 
      join y in List2 on x.Key1 equals y.Key2 
      select new { x, y}; // Or whatever 

foreach (var pair in pairs) 
{ 
    // Process each match 
} 

...하지만 더 컨텍스트없이 어떤 구체적인 도움을 제공하기 위해 거의 불가능 : NET은 LINQ 가입과 함께합니다.

-1

람다 식과 Linq

나는 루프를 멀리하고 시간을 절약 할 것이다. 달성하고자하는 것은 LINQ 쿼리로 수행 할 수 있다고 확신합니다.

예를 들어 다른 모음 내에서 값을 찾거나 다른 모음에서 항목 모음을 찾으려면 여기

이름으로 분류 예를 들어 ID가 다른 컬렉션에 포함되는 항목의 컬렉션을 얻을하는 방법을 예입니다

var result = from x in List1 
     where (from c in List2 
       select c.Id).Contains(x.Id) 
       select x).OrderByDescending(x => x.Name); 
+0

왜 이것을 downvoted했는지에 대한 의견이 있으십니까? – Shenaniganz

0

내가 N ((해시 테이블에 O를 양쪽 변환 제안))를 작성하고 각 목록을 스캔하고 O (1)을 다른 테이블에서 조회하여 현재 항목 (o (n) overall)이 들어 있는지 확인하십시오. 전체 O (n)이됩니다.

나는 ~ 1,000,000의 목록과 비슷한 것을 했어. 그리고 나는 보통 내가 기억하는 ~ 1 초 범위에서 끝난다.

관련 문제