【问题标题】:Fast selection of elements from a set, based on a property基于属性从集合中快速选择元素
【发布时间】:2011-10-16 12:18:44
【问题描述】:

如何存储大型集合的多个值,以便能够使用基于具有非唯一值的属性的 lambda 表达式快速找到它们?

示例案例(未针对性能进行优化):

class Product
{
    public string Title { get; set; }
    public int Price { get; set; }
    public string Description { get; set; }
}

IList<Product> products = this.LoadProducts();

var q1 = products.Where(c => c.Title == "Hello"); // 1 product.
var q2 = products.Where(c => c.Title == "Sample"); // 5 products.
var q3 = products.Where(c => string.IsNullOrEmpty(c.Title)); // 12 345 products.

如果标题是唯一的,则使用IDictionaryHashSet 可以轻松优化性能。但是值不唯一的情况呢?

【问题讨论】:

  • 可能是在Title 上排序的二叉搜索树(如果这是您需要找到的唯一属性)
  • 您的最后一个查询无法编译。你的意思是string.IsNullOrEmpty(c.Title)

标签: c# linq optimization query-optimization


【解决方案1】:

您需要的是在 LINQ 中运行索引查询的能力。 (和我们在 SQL 中做的一样)

有一个名为 i4o 的库显然可以解决您的问题:

http://i4o.codeplex.com/

来自他们的网站:

i4o(对象索引)是第一个扩展 LINQ 的类库 允许您在对象上放置索引。使用 i4o,速度 LINQ 操作通常比没有操作快一千多倍 i4o。

i4o 允许开发者指定一个 任何类的 IndexSpecification,然后使用 IndexableCollection 来实现该类的集合 将使用索引规范,而不是顺序搜索,当 执行可以从索引中受益的 LINQ 操作。

以下还提供了如何使用 i4o 的示例:

http://www.hookedonlinq.com/i4o.ashx

简而言之,您需要:

  1. 将 [Indexable()] 属性添加到您的“Title”属性中
  2. 使用 IndexableCollection 作为您的数据源。
  3. 从这一点开始,任何使用可索引字段的 linq 查询都将使用索引,而不是执行顺序搜索,从而导致使用索引的查询的性能提高幅度。

【讨论】:

  • 我还没有在制作中使用它,但很期待这样做。
【解决方案2】:

最简单的解决方案是使用Product 集合的字典。最简单的就是使用

var products = this.LoadProducts().ToLookup(p => p.Title);

var example1 = products["Hello"]; // 1 product
var example2 = products["Sample"]; // 5 products

你的第三个例子有点难,但你可以使用ApplyResultSelector()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2011-02-03
    相关资源
    最近更新 更多