2016-08-11 32 views
3

TL; DR版DataTable.Select VS List.FindAll

我有從數據庫或者以DataTable或在List<MyData>一些數據。

由於我想遵循O​​O原則,我更喜歡處理List<MyData>中的數據,但是當涉及到性能時,我遇到了一些麻煩。

對於大約150k項目,myDataList.FindAll(x=>x.Id == someId)需要大約15毫秒,而另一方面myDataTable.Select($"ID == {someId}")完成,而StopWatch能夠時鐘一毫秒。

因爲我需要在數據上執行數千次搜索,所以每次搜索15毫秒後就會加起來。

是否有任何其他列表類型我可以使用,而不是回落到DataRow[]DataTable.Select()返回?或者我在這裏錯過了其他的東西?

詳細版本

我有一個從數據庫中的兩個不同的表中讀取數據,需要計算這個數據的東西的應用程序。

按照面向對象原則,我得到了兩個對象列表:List<MyClass> myClassListList<MyOtherClass> myOtherClassList

由於兩個表中的數據之間存在關係(通過ID列),我現在想將它們移動到另一個類中,將它們組合到一個businessobject中:List<MyBusinessObject> myBusinessObjectList

所以我所做的就是以下幾點:

foreach (var id in myIdList) 
{ 
    var myTmpClassList = myClassList.FindAll(x => x.Id == id); 
    var myTmpOtherClassList = myOtherClassList.FindAll(x => x.Id == id); 

    myBusinessObjectList.Add(new MyBusinessObject(myTmpClassList, myTmpOtherClassList); 
} 

有了一個大致35K條目,並在其他表這個過程需要每次迭代約15毫秒,很快就增加了16萬項。

另一方面

var dic1 = new Dictionary<string, DataRow[]>; 
var dic2 = new Dictionary<string, DataRow[]>; 
foreach (var id in myIdList) 
{ 
    dic1.Add(id, myDataTable.Select($"ID == {id}"); 
    dic2.Add(id, myOtherDataTable.Select($"ID == {id}"); 
} 

完成在任何時間。

但由於我更喜歡​​處理Objects而不是Dictionary<string, DataRow[]>我想知道是否還有其他方法可以採取。

+0

你的財產比其他ID嘗試同樣的試驗?因爲我懷疑ID在DataTable中設置爲UniqueKey,因此有一個索引,當然,二分搜索比線性搜索要快得多。 –

+0

我沒有嘗試與另一個屬性,但'DataTable'沒有UniqueKey,所以我不期望有任何區別。 – sebingel

回答

2

這裏

foreach (var id in myIdList) 
{ 
    var myTmpClassList = myClassList.FindAll(x => x.Id == id); 
    var myTmpOtherClassList = myOtherClassList.FindAll(x => x.Id == id); 

    myBusinessObjectList.Add(new MyBusinessObject(myTmpClassList, myTmpOtherClassList); 
} 

執行2個線性搜索每每個 ID,導致O(K * (N + M))時間複雜度(其中K = myIdList.CountN = myClassList.CountM = myOtherClassList.Count)。

您可以使用LINQ group joins爲一個線性時間複雜度運行數據,其中使用了相當高效的基於散列的實現相關,從而導致:

var myBusinessObjectList = 
    (from id in myIdList 
    join x in myClassList on id equals x.Id into myClassGroup 
    join y in myOtherClassList on id equals y.Id into myOtherClassGroup 
    select new MyBusinessObject(myClassGroup.ToList(), myOtherClassGroup.ToList()) 
    .ToList(); 
+1

工程就像一個魅力。非常感謝你。我應該學習更多LINQ! – sebingel