C# 在C语言中如何有效地从一个巨大的列表中减去另一个#

C# 在C语言中如何有效地从一个巨大的列表中减去另一个#,c#,performance,collections,C#,Performance,Collections,我有一个很长的ID(整数)列表,它表示当前数据库中的所有项: var idList = GetAllIds(); List<T> itemsToAdd; 我还有一个巨大的通用列表,其中包含要添加到数据库中的项目: var idList = GetAllIds(); List<T> itemsToAdd; 我很确定它可以快得多,那么我应该为这两个集合使用什么数据类型,以及减去它们的最有效实践是什么 谢谢大家! 您应该使用两个HashSets. 请注意,它们是唯一且无

我有一个很长的ID(整数)列表,它表示当前数据库中的所有项:

var idList = GetAllIds();
List<T> itemsToAdd;
我还有一个巨大的通用列表,其中包含要添加到数据库中的项目:

var idList = GetAllIds();
List<T> itemsToAdd;
我很确定它可以快得多,那么我应该为这两个集合使用什么数据类型,以及减去它们的最有效实践是什么


谢谢大家!

您应该使用两个
HashSet
s.
请注意,它们是唯一且无序的。

LINQ可以帮助:

itemsToAdd.Except(idList)
您的代码很慢,因为
List.Contains
O(n)
。所以您的总成本是
O(itemsToAdd.Count*idList.Count)

您可以将idList设置为一个
哈希集
,其中包含
O(1)
。或者只使用Linq
。除了
扩展方法,它可以为您完成这项工作


请注意,
。除
外,还将从左侧删除所有重复项。i、 新的
int[]{1,1,2}。除了(新的int[]{2})
将导致只
{1}
,第二个1被删除。但我认为这在您的情况下没有问题,因为ID通常是唯一的。

临时将
idList
转换为
HashSet
,并使用相同的方法,即:

items.RemoveAll(e => idListHash.Contains(e.Id));

假设以下前提成立,它应该快得多

  • idList
    itemsToAdd
    不能包含重复的值
  • 您正在使用.NET Framework 4.0
您可以使用以下方法:

var itemsToAddSet = new HashSet(itemsToAdd);
itemsToAddSet.ExceptWith(idList);
根据文档,该方法非常有效:

此方法是O(n)操作, 其中n是中的元素数 另一个参数


在您的情况下,
n
idList

中的项目数。请注意,这也将排除
itemsToAdd
中的任何重复项。这是否是一个问题取决于OP(我怀疑不是,因为他们已经在示例中使用了
RemoveAll
)+1感谢您的精彩解释!我现在将idList构建为Hashset,但不能使用.Except(),因为itemsToAdd的类型为List/Hashset,idList的类型为Hashset。但是它速度更快,并且满足了我的需要。问题是itemsToAdd的类型是HashSet,idList的类型是HashSet。因此,我不能对这两个函数调用ExceptWith,需要将idList转换为一个会消耗大量内存的哈希集。
idList
不一定是一个
Hashset
,您只需要创建一个包含
itemsToAdd
的哈希集。然后将
idList
传递给
HashSet。除了作为
IEnumerable
之外。谢谢-这确实执行得快多了,这就是我所做的!如果可能的话,我想知道如何流式处理/枚举这些内容。。。