c# - 有没有比使用 Contains 方法更快的方法来搜索大型集合中是否存在实例?
问题描述
我有一个 C# 控制台应用程序,可将数据保存到 2 个 db 表、一个实体表和一个关系表。每个实体与其他实体具有多对多关系。关系表存储了一对 ID,它们又是实体表的主键。
两个表中的数据应该是唯一的。最初,我在数据库存储过程中插入新的个人记录之前检查了这一点。当两个表中的数字开始变大时(实体表中> 50k,关系表中> 100k),我注意到性能确实开始受到影响。
我认为由于增加了 I/O 成本,去数据库执行重复记录检查对性能有帮助,所以我重构了我的代码,首先将两个表读入内存,然后在那里执行检查。这提高了性能,尽管我怀疑它可能仍然不理想。这是它现在的样子:
private IEnumerable<long> _existingUsers = dao.GetUserIds();
private IEnumerable<Relations> _existingRelations = dao.GetRelations();
if (!_existingUsers.Contains(inputModel.ID))
{
// db code to create the new Entity record
}
Relations rel = new Relations { Node = inputModel.Node, Follower = inputModel.ID };
if (!_existingRelations.Contains(rel))
{
// db code to create the new Relation entry
}
关系类:
public class Relations : IEquatable<Relations>
{
public long Node { get; set; }
public long Follower { get; set; }
public bool Equals(Relations other)
{
return (other.Node == this.Node) && (other.Follower == this.Follower);
}
}
我可以通过调试器看到,现在大部分时间都用于确定内存中的 _existingRelations 集合是否包含“rel”实例。这反过来又反复命中了关系类的 Equals 方法。
我怀疑可能有更有效的方法来做到这一点,但我不知道那是什么。
解决方案
这取决于 IEnumerable 的具体实现。
这就是您contains
在列表中调用时发生的情况。在列表中搜索总是迭代所有列表以找到一个元素。所以没有更快的方法找到一个。
如果你称之为:https ://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1.contains?view=netcore-3.1那么你会得到一个O(1)
原样和HashSet
字典。
不利的一面是,哈希集没有排序。
推荐阅读
- .htaccess - 替换 URL 中的字符
- javascript - 编写一个脚本自动运行通过我的注册页面反应
- javascript - 在条带中添加自己的 CardHolder 名称
- c++ - 朋友模板运算符
- visual-studio-code - vscode 从以前的同步中恢复扩展
- git - 从原始提交更改提交日期
- multithreading - Tkinter 滚动条干扰线程打印到文本小部件
- sql - SQL/ACCESS 单向一对一关系数据完整性
- java - 带有 Java Hibernate 和 Jersey 后端的 AWS Cognito
- ios - SwiftUI Group of Text + Link -> 编译器错误