性能最佳的可搜索收集策略?

时间:2013-05-09 08:53:58

标签: c# performance linq collections

我有一个具有以下界面的对象集合:

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

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

的IList< IEntity>

将它们粘贴在列表中,使用linq过滤它们

的IDictionary<元组< string,string>,IEntity>

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

其他

还有其他更好的方法来实现这个目标吗?

4 个答案:

答案 0 :(得分:2)

对于基于键的快速查找,您无法比关联容器做得更好:哈希表(如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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

有些事情可行:

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

答案 3 :(得分:0)

所以,我有IEnumerable<IEntity>,如果键是独立的,那么它很简单,

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]);
相关问题