【问题标题】:Linq contains for compairing two huge list takes long timeLinq 包含用于比较两个巨大的列表需要很长时间
【发布时间】:2018-04-10 06:28:12
【问题描述】:

当我想将一个巨大的列表(大约 700,000 个元素)与特定属性和字符串列表进行比较时,需要很长时间。

我尝试了 AsParallel,但它不再帮助我了。我需要removedSuccessFromList 的列表,因为我想使用这个列表来启动Parallel.Foreach

List<string> successStrings = service.GetProperty().Select(q => 
q.IdString).ToList();

List<Property> removedSuccessFromList = properties.AsParallel().Where(q => 
!successStrings.Contains(q.IdString)).ToList();

【问题讨论】:

  • “需要很长时间”...该基准是如何实现的?您如何将一个“长时间”与另一个“长时间”进行比较?
  • successStrings 有多大? properties 有多大?尺寸很重要
  • @Evk 我假设 properties 是 700k,但是:是的,最好知道两个输入的大小

标签: c# .net performance list linq


【解决方案1】:

如果successStrings 中有很多字符串,请使用更有效的数据结构,例如哈希集:

var successStrings = new HashSet<string>(service.GetProperty().Select(q => q.IdString));

List<Property> removedSuccessFromList = properties.Where(q => !successStrings.Contains(q.IdString)).ToList();

List.Contains 方法的复杂度为 O(N),因此它会扫描所有元素以找到匹配项。 HashSet.Contains 的复杂度为 O(1) - 它可以检查元素是否存在非常大。

【讨论】:

  • 请注意,O(1) 可能比 O(N) 慢,尤其是对于小 N。这是否是实际改进很大程度上取决于 successStrings 的大小
【解决方案2】:

如果您的IdString 是唯一的,也许您可​​以从Where 逻辑中的successStrings 中删除每个已创建的项目,这样列表最终会变小

【讨论】:

  • 这不会自动成为改进;并且由于 OP 使用并行,它会引入同步的需要,这可能会增加显着的影响
  • @MarcGravell 是的,我建议不要使用并行,仅在 16 核上运行 O(N) 算法。在一个核心上运行更好的算法应该更有效
  • 这个方法也需要很长时间,但我可以看到进度。
猜你喜欢
  • 1970-01-01
  • 2022-06-20
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多