DataTable.Select 对比 List.FindAll
DataTable.Select vs List.FindAll
TL;DR 版本
我在 DataTable
或 List<MyData>
中有一些来自数据库的数据。
因为我想遵循 OO 原则,所以我更喜欢在 List<MyData>
中处理数据,但是当涉及到性能时,我 运行 遇到了一些麻烦。
对于大约 150k 个项目,myDataList.FindAll(x=>x.Id == someId)
大约需要 15 毫秒,而在另一侧,myDataTable.Select($"ID == {someId}")
完成而 StopWatch
无法计时一毫秒。
因为我需要对我的数据执行数千次搜索,每次搜索 15 毫秒的时间加起来很快。
我可以使用任何其他列表类型来代替回退到 DataTable.Select()
returns 的 DataRow[]
吗?还是我在这里遗漏了其他东西?
详细版
我有一个应用程序从数据库中的两个不同 table 中读取数据,并且需要对这些数据进行一些计算。
遵循 OO 原则,我得到了两个对象列表:List<MyClass> myClassList
和 List<MyOtherClass> myOtherClassList
。
由于两个 table 中的数据之间存在关系(通过 ID 列),我现在想将它们移动到另一个 class 中,将它们组合成一个业务对象: 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 个条目,另一个有 160k 个条目table这个过程每次迭代大约需要 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[]>
,我想知道是否还有其他方法可以采用。
这里
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.Count
、N = myClassList.Count
、M = 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();
TL;DR 版本
我在 DataTable
或 List<MyData>
中有一些来自数据库的数据。
因为我想遵循 OO 原则,所以我更喜欢在 List<MyData>
中处理数据,但是当涉及到性能时,我 运行 遇到了一些麻烦。
对于大约 150k 个项目,myDataList.FindAll(x=>x.Id == someId)
大约需要 15 毫秒,而在另一侧,myDataTable.Select($"ID == {someId}")
完成而 StopWatch
无法计时一毫秒。
因为我需要对我的数据执行数千次搜索,每次搜索 15 毫秒的时间加起来很快。
我可以使用任何其他列表类型来代替回退到 DataTable.Select()
returns 的 DataRow[]
吗?还是我在这里遗漏了其他东西?
详细版
我有一个应用程序从数据库中的两个不同 table 中读取数据,并且需要对这些数据进行一些计算。
遵循 OO 原则,我得到了两个对象列表:List<MyClass> myClassList
和 List<MyOtherClass> myOtherClassList
。
由于两个 table 中的数据之间存在关系(通过 ID 列),我现在想将它们移动到另一个 class 中,将它们组合成一个业务对象: 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 个条目,另一个有 160k 个条目table这个过程每次迭代大约需要 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[]>
,我想知道是否还有其他方法可以采用。
这里
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.Count
、N = myClassList.Count
、M = 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();