我试图找到一些关于我的问题的文章,但没有找到任何相关或对我的应用程序有意义的文章。这是我的问题:
我有两个(> 20,000)项目列表。
我需要针对相反列表中的每个项目检查每个列表中的每个项目。
这样的实现:
foreach(var item1 in List1)
{
foreach(var item2 in List2)
{
// Check item 1 against item 2.
// Check item 2 against item 1.
}
}
由于检查工作,极其缓慢且无法使用。
是否有更有效的方法来处理需要像这样检查的大型商品列表?
如果我能提供更多信息,请告诉我。 感谢您的任何帮助/建议。
我正在使用C#.NET 3.5
编辑:让我试着以简单的方式解释检查。item1和item2是路径系统的一部分。 item1和item2由N个其他项连接。我正在检查item1是否与item2连接(有效路径),而item2连接到item1。不能假设如果item1 - > item2,而不是item2 - >物品1。所以两次检查都是必要的。
数据库包含有关item1 - >的信息。 item2和if / how item2 - >物品1。 在检查内部,有一个命名管道调用服务来进行检查。如果item1 - >该服务执行所有路径检查并返回第2项等。
答案 0 :(得分:3)
这是O(N * M)
支票。
如果你只是比较某些键或其他键上的相等性,那么你可以通过O(N + M)次迭代,假设合理的哈希码和良好的键分布。在.NET中执行此操作的最简单方法是使用LINQ连接:
var pairs = from x in List1
join y in List2 on x.Key1 equals y.Key2
select new { x, y}; // Or whatever
foreach (var pair in pairs)
{
// Process each match
}
当然,如果你不检查是否相等,这无济于事......但如果没有更多的背景,几乎不可能提供任何具体的帮助。
答案 1 :(得分:2)
长循环+数据库查询=糟糕的表现。
您应该尝试做的是先运行一些查询,获取所需的数据,然后对该数据进行N x M检查。
当然,这不一定是可能的;真的取决于你正在做的检查种类。
答案 2 :(得分:1)
尽量避免每次迭代向数据库发出请求的情况。在可能的情况下,尝试在循环外部进行所有查询,或者在循环外部获取所需数据,然后对此数据进行检查。
全部取决于检查操作。所以描述一下。但无论如何,如果你的迭代是独立的,你也可以使用PLINQ和Task Parallel Libary并行化你的循环
答案 3 :(得分:0)
我建议将双方转换为每个表的哈希表(O(n))并扫描每个列表并在另一个表中查找O(1)以检查它是否包含当前项(o( n)总体而言。这导致整体O(n)。
我已经完成了类似于~100,000的列表的事情,它通常在我记忆的〜1秒范围内完成。
答案 4 :(得分:-1)
Lambda表达式和Linq
我会节省时间并远离循环。我确信无论你想要实现什么,都可以通过LINQ查询完成。
例如,在另一个集合中查找值或查找另一个集合中的项集合。
下面是一个示例,说明如何通过ID获取另一个集合中包含的项目集合,例如按名称排序:
var result = from x in List1
where (from c in List2
select c.Id).Contains(x.Id)
select x).OrderByDescending(x => x.Name);