提高List <t>的性能

时间:2016-09-01 18:35:57

标签: c#

我有一个名为Product的类,它包含一些属性,如Id(作为Guid)和Messages(作为List),以及一个也包含Id和其他属性的Message类。我在Message表中有所有消息,在product表中有所有产品。获取两个表的数据后,我想在Id属性上加入它们。如果我使用下面的代码,因为它是线性搜索,性能很糟糕。

foreach (Product product in products)
    product.Messages = messages.Where(n => n.Id == product.Id).ToList();

还有其他方法可以更快地完成吗?

由于

3 个答案:

答案 0 :(得分:2)

您可以通过将消息分组到查找表中来加快速度。

messagesDict = messages
    .GroupBy(x => x.Id)
    .ToDictionary(x => x.Id, x.ToList());

或者,正如John Bustos建议的那样,你可以使用ToLookup();

messagesDict = messages
    .ToLookup(x => x.Id);

你像这样使用它

//you might have to first check if messagesDict 
//actually has any messages for your project.
product.Messages = messagesDict[product.Id];

您的原始尝试是 O(nm),其中 n 是项目数, m 是消息数。

Dictionary使用散列,因此从实用的角度来看,您通常可以假设它接近 O(1)插入,并且 O(1)搜索。 Under ideal circumstancesList<T>.Add也是 O(1)。这意味着如果您要手动创建查找字典,则可以在 O(m)中执行此操作。我希望像ToLookup这样的内置函数能达到同样的效率。

一旦你这样做,你的algorthim变成 O(n + m)

答案 1 :(得分:0)

您应该在数据库中进行连接。这将产生最佳性能。如果您坚持在C#中按ID生成产品并按ID排序消息。

答案 2 :(得分:0)

正如其他人所指出的那样,在数据库中进行连接。正如您所指出的,线性搜索是O(n)(在这种情况下,您实际上正在进行相当多的线性搜索);但是,大多数数据库使用B树数据结构(或类似的东西)按主键对行进行排序。这意味着对主键的数据库搜索是O(log n),显然显着更快。 (当然,假设Id是主键)。