2012-06-20 48 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

從邏輯上講,你正在做某種「加入」,你應該用這種方式實現它,使用內置到你的數據庫中的機制(和優化)...... –

回答

1

儘量避免每次迭代發出數據庫請求時的情況。在可能的情況下,儘量在循環之外完成一個查詢,或者在循環之外獲取所需的數據,然後對這些數據進行檢查。

一切都取決於檢查操作。所以描述它們。但無論如何,如果你的迭代是獨立的,你也可以使用PLINQ和任務並行Libary

Data Parallelism (Task Parallel Library)

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

長循環+數據庫查詢=可怕的性能。

你應該嘗試做的事是首先運行一些查詢,獲取你需要的數據,然後對這些數據進行N×M次檢查。

這當然不一定可行;真的取決於你正在做的檢查種類。

+0

林不知道根據我的條件這是可能的。每個item1必須去檢查中調用的服務來驗證路線。 – therealjohn

3

這是一個O(N * M)檢查並行化循環。假設一個合理的散列碼和一個良好的密鑰分佈,你可以通過O(N + M)迭代得到結果。最簡單的方法來做到這一點。NET是一個LINQ加入:

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 
} 

當然,如果你不檢查平等,這不利於...但是這幾乎是不可能給任何具體的幫助,沒有更多的上下文。

-1

Lambda表達式和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

小心評論你爲什麼低估了這個? – Shenaniganz

0

我建議雙方轉換成哈希表(O(N )),並掃描每個列表,並在另一個表中執行O(1)查找,以檢查它是否包含當前項目(整體o(n))。這導致整體O(n)。

我已經做了類似的約1,000,000列表,它通常在我記得的〜1秒範圍內完成。