gpt4 book ai didi

c# - 跨多个属性搜索 List 的最快方法是什么?

转载 作者:行者123 更新时间:2023-12-04 02:44:06 25 4
gpt4 key购买 nike

我有一个继承的过程,我正在从另一种语言转换为 C#。流程中的许多步骤都可以通过大量记录(100K-200K)来进行计算。作为这些过程的一部分,它通常会查找另一个列表以检索一些值。我通常会将这种事情移到 SQL 语句中(并且我们已经能够做到这一点),但在这些情况下,并没有真正简单的方法来做到这一点。在某些地方,我们试图将代码转换为存储过程,但发现它的工作效果几乎没有我们希望的那么好。

代码实际上是这样做的:

var match = cost.Where(r => r.ryp.StartsWith(record.form.TrimEnd()) && 
r.year == record.year &&
r.period == record.period).FirstOrDefault();

cost 是本地列表类型。如果我只搜索一个字段,我可能会把它移到字典中。记录也不总是唯一的。

显然,这真的很慢。

跑到开源库 I4O它可以构建索引,但是它在各种查询中都失败了(而且我真的没有时间尝试调试源代码)。它也不适用于 .StartsWith 或 .Contains(StartsWith 更为重要,因为许多原始查询利用了搜索“A”会在“ABC”中找到匹配项这一事实)。

有没有其他项目(开源或商业)做这种事情?

编辑:

我根据反馈做了一些搜索,找到了 Power Collections它支持具有非唯一键的字典。

我测试了 ToLookup() 效果很好 - 它仍然没有原始代码那么快,但至少可以接受。它从 45 秒减少到 3-4 秒。我将看看其他查找的 Trie 结构。

谢谢。

最佳答案

循环遍历 100K-200K 项目的列表不会花费很长时间。通过使用嵌套循环 (n^2) 在列表中查找匹配项确实需要很长时间。我推断这就是您正在做的事情(因为您已分配给本地匹配变量)。

如果您想快速将项目匹配在一起,请使用 .ToLookup .

var lookup = cost.ToLookup(r => new {r.year, r.period, form = r.ryp});

foreach(var group in lookup)
{
// do something with items in group.
}

您的开始条件对于基于键的匹配来说很麻烦。解决该问题的一种方法是在生成 key 时忽略它。
var lookup = cost.ToLookup(r => new {r.year, r.period });
var key = new {record.year, record.period};
string lookForThis = record.form.TrimEnd();
var match = lookup[key].FirstOrDefault(r => r.ryp.StartsWith(lookForThis))

理想情况下,您将创建一次查找并将其重用于许多查询。即使你没有......即使你每次都创建了查找,它仍然会比n^2快。

关于c# - 跨多个属性搜索 List<T> 的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10109670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com