You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中高效对比两个百万级对象列表的最优方案

优化百万级列表对比的最优方案

嘿,我太懂你这种感受了——用嵌套循环处理百万级数据,那速度慢得简直让人想砸键盘!你现在的代码里,不管是ForEach搭配Any()还是普通for循环,本质上都是**O(n*m)**的时间复杂度:每遍历SourceList里的一个元素,就要把整个TargetList扫一遍,百万乘百万就是1万亿次操作,这能快才怪呢。

核心优化思路:用哈希集合把查找成本降到O(1)

解决这类问题的关键,是把需要频繁查找的TargetList的Name字段提前存入一个HashSet里。HashSet的查找操作是常数时间O(1),这样整体复杂度就降到了O(n + m),操作量直接从1万亿降到200万,性能提升几个数量级不在话下。

具体实现代码

假设你的对象有一个Name属性(这里以字符串类型为例,如果是其他类型,只要能正确哈希即可),优化后的代码如下:

// 第一步:把TargetList中所有Name提取到HashSet,这一步是O(m)时间
var targetNameSet = new HashSet<string>(TargetList.Select(item => item.Name));

// 第二步:遍历SourceList,筛选不在HashSet中的元素,这一步是O(n)时间
var DifferentList = SourceList.Where(sourceItem => !targetNameSet.Contains(sourceItem.Name)).ToList();

额外注意事项

  • 如果Name可能为null,记得提前过滤,避免空引用异常:
    var targetNameSet = new HashSet<string>(TargetList.Where(item => item.Name != null).Select(item => item.Name));
    var DifferentList = SourceList.Where(sourceItem => sourceItem.Name != null && !targetNameSet.Contains(sourceItem.Name)).ToList();
    
  • 如果你的对象的Name是自定义类型,一定要确保该类型正确实现了GetHashCode()和Equals()方法,否则HashSet无法正确判断元素是否存在。
  • 如果你习惯用for循环而不是LINQ,也可以这么写,性能几乎没差别:
    var targetNameSet = new HashSet<string>(TargetList.Select(item => item.Name));
    var DifferentList = new List<object>();
    for (int i = 0; i < SourceList.Count; i++)
    {
        var currentItem = SourceList[i];
        if (!targetNameSet.Contains(currentItem.Name))
        {
            DifferentList.Add(currentItem);
        }
    }
    

为什么这是最优解?

哈希集合是处理这类存在性检查问题的标准工具,它在内存占用和查找速度之间做了完美平衡。百万级的字符串存入HashSet,内存占用完全在合理范围内(大概几十MB),而查找速度比List的线性查找快几个数量级,绝对是处理这类问题的首选方案。

内容的提问来源于stack exchange,提问作者Sarvesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:02:49