demo代码如下:
class Program
{
static void Main(string[] args)
{
DataTable table1 = new DataTable();
table1.Columns.Add("Id");
table1.Columns.Add("Name");
table1.Columns.Add("Age");
DataTable table2 = new DataTable();
table2.Columns.Add("Id");
table2.Columns.Add("Name");
table2.Columns.Add("Age");
for (int i = 0; i < 150000; i++)
{
var dr = table1.NewRow();
dr[0] = i.ToString();
dr[1] = "Name" + i.ToString();
dr[2] = 23;
table1.Rows.Add(dr);
if (i<=140000)
{
var dr1 = table2.NewRow();
dr1[0] = i.ToString();
dr1[1] = "Name" + i.ToString();
dr1[2] = 23;
table2.Rows.Add(dr1);
}
}
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var same = table1.AsEnumerable().Where(t1 => table2.AsEnumerable().Select(t2 => t2.ItemArray[0].ToString()).Contains(t1.ItemArray[0].ToString())).ToList();
stopwatch.Stop();
var sec1 = stopwatch.ElapsedMilliseconds;
}
}
class student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
经过测试 sec1=2030054毫秒
等待的时间太长,哪位大神 能指明下方向,如何提升性能
List<T> list1; List<T> list2;
class eq:IEqualityComparer<T>{
bool Equals(T x, T y)=> x.Id==y.Id
int GetHashCode(T t){}
// 你自己的逻辑判断2个对象是否相等.
}
list1.Except(list2, new eq()); //差集,
list1.Intersect (list2, new eq()); Intersect 交集
感谢您的回复 我已经用except intertsect实现了 比where过滤快好多 了解到where底层是foreach 但是还未了解 except 与 intertsect的底层
@丨渊丨: 内部实现是foreach
循环+ Set<T>
结构来实现的
@czd890: 感谢您的讲解
我觉得放到hash表(或字典)里可能是最快的,用id作为key。我现在没时间,要不你试试
真实的业务 主键都是guid 连续或者排序 我就没考虑这样处理了
id一样 不能认为两条数据一样 ,因为字段可能不同,id一样只能代表既在A表中存在也在B表中存在.
感谢您的回复🙏
@丨渊丨: 认为两个数据相同的条件是什么?看你写的代码是:tostring()一样就算相同
@会长:(前提:A表结构与B表结构相同) 一条行记录 既在A表中存在 也在B表中存在 (主键相同 )且A表的每一个字段值与B表的字段值相同 即可判定 两个数据相同
@会长: 描述有点偏差,
因该是主键相同的记录,并且每个字段值都相同,就可认为数据相同
@丨渊丨: 那就是:所有字段都相等就认为两个数据相等了
@丨渊丨: 你直接写sql查询,速度怎么样?如果这两表在一个数据库的话
@会长: 目前应该找到提升性能的方向了 用微软封装好的 except 与 intersect 性能有巨大提升 比where过滤要好用很多 非常感谢您与我探讨
可以考虑使用Redis的Set数据结构来实现集合的交/叉集 计算。非常方便快捷。
不考虑依赖的
本地处理也是可以的。10w级别的数据量并不是很大。图中的方式实际是 通过循环查询对比,时间复杂度o(n*n)了。所以肯定慢。
如楼上,考虑空间替换时间的方式。用Hash存储,过滤一遍即可找到交集合。时间复杂度o(n)。就很快了
感谢您的答复 给我扩宽了思路