首页 新闻 会员 周边

两个泛型集合,字段一致,两个的数据规模大概在10w左右的数据量,如何快速的得到交集,差集

0
悬赏园豆:10 [已解决问题] 解决于 2021-07-14 08:54

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毫秒

等待的时间太长,哪位大神 能指明下方向,如何提升性能

丨渊丨的主页 丨渊丨 | 初学一级 | 园豆:71
提问于:2021-05-26 01:52
< >
分享
最佳答案
0

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 交集

收获园豆:7
czd890 | 专家六级 |园豆:14412 | 2021-05-26 17:49

感谢您的回复 我已经用except intertsect实现了 比where过滤快好多 了解到where底层是foreach 但是还未了解 except 与 intertsect的底层

丨渊丨 | 园豆:71 (初学一级) | 2021-05-26 17:51

@丨渊丨: 内部实现是foreach循环+ Set<T>结构来实现的

czd890 | 园豆:14412 (专家六级) | 2021-05-26 17:54

@czd890: 感谢您的讲解

丨渊丨 | 园豆:71 (初学一级) | 2021-05-26 17:57
其他回答(2)
0

Id一样就可以认为两个数据相同吗?
是否是按id从小到大排序的?
Id是否一定连续?

我觉得放到hash表(或字典)里可能是最快的,用id作为key。我现在没时间,要不你试试

收获园豆:1
会长 | 园豆:12401 (专家六级) | 2021-05-26 09:15

真实的业务 主键都是guid 连续或者排序 我就没考虑这样处理了
id一样 不能认为两条数据一样 ,因为字段可能不同,id一样只能代表既在A表中存在也在B表中存在.
感谢您的回复🙏

支持(1) 反对(0) 丨渊丨 | 园豆:71 (初学一级) | 2021-05-26 09:19

@丨渊丨: 认为两个数据相同的条件是什么?看你写的代码是:tostring()一样就算相同

支持(0) 反对(1) 会长 | 园豆:12401 (专家六级) | 2021-05-26 09:22

@会长:(前提:A表结构与B表结构相同) 一条行记录 既在A表中存在 也在B表中存在 (主键相同 )且A表的每一个字段值与B表的字段值相同 即可判定 两个数据相同

支持(0) 反对(0) 丨渊丨 | 园豆:71 (初学一级) | 2021-05-26 09:26

@会长: 描述有点偏差,
因该是主键相同的记录,并且每个字段值都相同,就可认为数据相同

支持(0) 反对(0) 丨渊丨 | 园豆:71 (初学一级) | 2021-05-26 09:32

@丨渊丨: 那就是:所有字段都相等就认为两个数据相等了

支持(0) 反对(0) 会长 | 园豆:12401 (专家六级) | 2021-05-26 11:41

@丨渊丨: 你直接写sql查询,速度怎么样?如果这两表在一个数据库的话

支持(0) 反对(0) 会长 | 园豆:12401 (专家六级) | 2021-05-26 11:43

@会长: 目前应该找到提升性能的方向了 用微软封装好的 except 与 intersect 性能有巨大提升 比where过滤要好用很多 非常感谢您与我探讨

支持(0) 反对(0) 丨渊丨 | 园豆:71 (初学一级) | 2021-05-26 11:44
0

可以考虑使用Redis的Set数据结构来实现集合的交/叉集 计算。非常方便快捷。
不考虑依赖的
本地处理也是可以的。10w级别的数据量并不是很大。图中的方式实际是 通过循环查询对比,时间复杂度o(n*n)了。所以肯定慢。
如楼上,考虑空间替换时间的方式。用Hash存储,过滤一遍即可找到交集合。时间复杂度o(n)。就很快了

收获园豆:2
gt1987 | 园豆:1150 (小虾三级) | 2021-05-26 13:50

感谢您的答复 给我扩宽了思路

支持(0) 反对(0) 丨渊丨 | 园豆:71 (初学一级) | 2021-05-26 15:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册