开发者

Fast selection of elements from a set, based on a property

开发者 https://www.devze.com 2023-03-23 19:40 出处:网络
How can I store multiple values of a large set to be able to find them quickly with a lambda expression based on a property with non-unique values?

How can I store multiple values of a large set to be able to find them quickly with a lambda expression based on a property with non-unique values?

Sample case (not optimized for performance):

class Product
{
    public string Title { get; set; }
    public int Price { get开发者_StackOverflow中文版; 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.

If title was unique, it would be easy to optimize performance by using IDictionary or HashSet. But what about the case where the values are not unique?


The simplest solution is to use a dictionary of collections of Product. Easiest is to use

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

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

Your third example is a little harder, but you could use ApplyResultSelector() for that.


What you need is the ability to run indexed queries in LINQ. (same as we do in SQL)

There is a library called i4o which apparently can solve your problem:

http://i4o.codeplex.com/

from their website:

i4o (index for objects) is the first class library that extends LINQ to allow you to put indexes on your objects. Using i4o, the speed of LINQ operations are often over one thousand times faster than without i4o.

i4o works by allowing the developer to specify an IndexSpecification for any class, and then using the IndexableCollection to implement a collection of that class that will use the index specification, rather than sequential search, when doing LINQ operations that can benefit from indexing.

also the following provides an example of how to use i4o:

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

Make it short you need to:

  1. Add [Indexable()] attribute to your "Title" property
  2. Use IndexableCollection<Product> as your data source.
  3. From this point, any linq query that uses an indexable field will use the index rather than doing a sequential search, resulting in order of magnituide performance increases for queries using the index.
0

精彩评论

暂无评论...
验证码 换一张
取 消