我有两个系列:
private void ProcessCollectionsData(List<OrganizationUser> databaseUsers, List<OrganizationUser> importedUsers) { ... }
有一个名为UserIdentifier(String)和UserId(Int32)的属性。这就是我比较它们产生错误结果和严重性能瓶颈的方法:
LogMessage(new LogEntry(" - Generating delta for new users...", true));
Task.WaitAll(Task.Run(() =>
{
newUsers = databaseUsers.Any() ? importedUsers.Where(x => !databaseUsers.Select(y => y.UserIdentifier.ToLower())
.ToList()
.Contains(x.UserIdentifier.ToLower()))
.ToList()
: importedUsers;
duplicates = newUsers.OrderByDescending(o1 => o1.UserId)
.GroupBy(s => s.UserIdentifier, StringComparer.InvariantCultureIgnoreCase)
.Where(y => y.Count() > 1);
foreach (var item in duplicates)
{
newUsers.RemoveAll(s => string.Equals(s.UserIdentifier, item.Key, StringComparison.OrdinalIgnoreCase));
newUsers.Add(item.First());
}
}));
LogMessage(new LogEntry(String.Format(" - Done. New users to be imported: {0}", newUsers.Count)));
importedUsers
中的数据来自CSV,可以复制,也可以使用UserIdentifier
字段的混合大小写进行复制。第一次databaseUsers
中的数据为空。然后,在第一次运行后,导入文件将大约100,000个用户转储到数据库,并且在第二次和连续运行时,databaseUsers
加载了100,000个现有用户,importedUsers
也将数据范围设置为99,990到100,100(示例),它要求我生成增量集合,以便我知道哪些用户标记删除,添加(新)和剩余(常见)需要更新。
有人能建议更快的方法吗?
我可以看到我在使用ToLower()
分配给newUser
集合时犯了一个错误
对上述声明进行更正后,生成的newUsers
集合会根据需要保留案例信息。所以现在这里的表现是真正的问题。
答案 0 :(得分:1)
我认为你的性能问题的关键在于
!databaseUsers.Select(y => y.UserIdentifier.ToLower()).ToList()
鉴于databaseUsers
可以包含100,000个用户,您当然不希望将整个列表拉入内存。摆脱Select
/ ToList
调用应该意味着您只查询应该有所作为的数据库
importedUsers.Where(x => !databaseUsers.Any(y =>
y.UserIdentifier.ToLower() == x.UserIdentifier.ToLower()).ToList()