【发布时间】:2019-11-12 18:36:54
【问题描述】:
我需要过滤List<object>,以便删除另一个List<string> 中不存在string 属性的任何项目。
我创建这个控制台应用程序只是为了确保我的 LINQ 语法正确:
class FooBar
{
public int Id { get; set; }
public string ValueName { get; set; }
}
然后……
List<FooBar> foobars = new List<FooBar>
{
new FooBar { Id = 1, ValueName = "Val1" },
new FooBar { Id = 2, ValueName = "Val2" },
new FooBar { Id = 3, ValueName = "Val3" },
new FooBar { Id = 4, ValueName = "Val4" }
};
List<string> myStrings = new List<string>
{
"Val1",
"Val3"
};
// Only keep records where ValueName is found in `myStrings`
foobars = foobars.Where(f => myStrings.Contains(f.ValueName)).ToList();
所以,这一行:
foobars = foobars.Where(f => myStrings.Contains(f.ValueName)).ToList();
做的正是我想要的,它给了我这两条记录:
{ Id = 1, ValueName = "Val1" }
{ Id = 3, ValueName = "Val3" }
一切都好。但是......在实际应用中,foobars 有超过 200k 个项目,myStrings 有大约 190k。而当执行该 LINQ 行时,需要 5 分钟以上才能完成。
我显然做错了什么。 20 万条记录并没有那么大。而真正的FooBar 并没有那么复杂(没有嵌套对象,只有 9 个属性)。
这是怎么回事?
【问题讨论】:
-
你的列表都排序了吗?因为this而问
-
如果它在内存中,那似乎很长一段时间。如果您实际上正在做的是访问数据库并使用
Contains,那么您将撤回 190k 条记录,同时避免使用数据库的索引。你在使用数据库吗? -
使用
HashSet<string> myStrings而不是List<string> -
2*4 与您的实际代码几乎相当,它执行 200K*190K 字符串比较 (38,000,000,000)。使用更好的数据结构,例如 HashSet。
-
@JustinLessard,不,没有排序。我会将它们都排序并重试。
标签: c# .net performance linq