【问题标题】:Best searchable collection strategy for performance?性能的最佳可搜索收集策略?
【发布时间】:2013-05-03 16:52:43
【问题描述】:

我有一组具有以下界面的对象:

public IEntity
{
    public string Key1 { get; set; }
    public string Key2 { get; set; }
    ... some other properties
}

并且正在寻找通过 linq 查询这些对象的内存集合的最佳策略。大多数查询(但不是全部)可能会寻找 Key1 或 Key2 来访问实体,所以我不确定查询它们的最高效方式是什么。我的想法是:

IList

只需将它们放在一个列表中,然后使用 linq 过滤它们

IDictionary, IEntity>

使用 key1 和 key2 创建一个多键字典,但如果我只知道一个部分,我不确定如何访问 IEntity?

别的东西

还有其他更好的方法来实现这一点吗?

【问题讨论】:

  • 全部取决于您要执行的搜索类型。
  • 实现什么?键是复合的还是独立唯一的?

标签: c# performance linq collections


【解决方案1】:

对于基于键的快速查找,您无法比关联容器做得更好:要么是像 Dictionary 这样的哈希表,要么是像 SortedDictionary 这样的基于树的结构。在相对不常见的情况下,您的数据结构是从排序的输入构建一次并且很少修改的,也可以考虑SortedList。所有这些都有不同的性能特征,因此选择取决于具体情况。

如果您的密钥具有不同的类型,那么您实际上必须使用多个这样的容器,但在这里您可以只使用一个并为每个“密钥类型”赋予唯一的前缀。例如,您可以决定这样做:

var dict = new Dictionary<string, IEntity>();
var entity = (IEntity)whatever;

dict.Add("key1:" + entity.Key1, entity);
dict.Add("key2:" + entity.Key2, entity);

// and now find by either Key1 or Key2 by using the same prefix

如果不能保证键是唯一的,那么您将需要一个“MultiDictionary”或等效类,在这种情况下,您应该查看问题multimap in .NET

【讨论】:

    【解决方案2】:

    您的列表将采用 O(n) 进行搜索,而字典应该采用 O(1) 的内存大小。所以你的字典方法将是最快的

    【讨论】:

      【解决方案3】:

      有几件事可能会奏效:

      • 如果您可以接受仅使用列表并扫描它们的性能,那么您就完成了!
      • 您可以使用 2 个以上的字典:IDictionary&lt;string,List&lt;IEntity&gt;&gt;。 Dictionary1 键入 Key1,Dictionary2 键入 Key2 等。将所有实体存储在具有该键的列表中。根据您没有通过字典索引的属性,接受较差的查找性能。
      • 可能使用trie 数据结构。

      【讨论】:

        【解决方案4】:

        所以,我有一个IEnumerable&lt;IEntity&gt;,如果键是独立的 unqiue 那么它很简单,

        IEnumerable<IEntity> entities = ...
        
        var byKey1 = entities.ToDictionary(e => e.Key1);
        var byKey2 = entities.ToDictionary(e => e.Key2);
        

        如果不是,

        var byKey1 = entities.ToLookup(e => e.Key1);
        var byKey2 = entities.ToLookup(e => e.Key2);
        

        那么,如果你有两个键,

        var match = byKey1[key1].Intersect(byKey2[key2]);
        

        【讨论】:

          猜你喜欢
          • 2023-03-11
          • 2020-06-06
          • 2023-03-04
          • 2021-02-07
          • 1970-01-01
          • 2021-08-08
          • 2016-10-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多