DataTable.Select vs List.FindAll

时间:2016-08-11 16:04:24

标签: c# performance list datatable lookup

TL; DR版本

我在DataTableList<MyData>中拥有数据库中的一些数据。

由于我想遵循O​​O原则,我更愿意处理List<MyData>中的数据,但是当涉及到性能时,我遇到了一些麻烦。

大约150k项目myDataList.FindAll(x=>x.Id == someId)大约需要15毫秒,而另一方myDataTable.Select($"ID == {someId}")完成,而StopWatch无法计时一毫秒。

由于我需要对我的数据执行数千次搜索,因此每次搜索15毫秒即可累计。

我可以使用其他任何List-Type而不是回退到DataRow[]返回的DataTable.Select()吗?或者我在这里错过了其他什么?

详细版本

我有一个应用程序从数据库中的两个不同的表读取数据,需要计算这些数据的内容。

根据OO原则,我得到了两个对象列表:List<MyClass> myClassListList<MyOtherClass> myOtherClassList

由于两个表中的数据之间存在关系(通过ID列),我现在想将它们移动到另一个将它们组合到业务对象的类中: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 );
}

在另一个表中一个和160k条目中大约有35k个条目,这个过程每次迭代大约需要15毫秒,很快就会加起来。

另一方面

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[]>我想知道是否还有其他方法可以采取。

1 个答案:

答案 0 :(得分: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 );
}

您为每个 ID执行2次线性搜索,导致O(K * (N + M))时间复杂度(K = myIdList.CountN = myClassList.CountM = myOtherClassList.Count)。< / p>

您可以使用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();