i4o是对LINQ的一个扩展,通过允许我们在对象上添加“索引”来提高LINQ运算速度,作者号称使用i4o后速度提升often over one thousand times。
我们在进行数据库查询优化时,往往第一想到的就是给Tables添加合适的Index来大幅度提升执行效率,i4o的实现也是类似这个方式,我们只要给class添加一个Indexable属性,然后使用IndexableCollection<T>来实现一个使用“索引”的类的集合就可以了,这样比起顺序性的搜索就在一定程度上提高了速度。
比如我们可以这样用:
1var customers = new IndexableCollection<CnblogUser>() {
2 new Customer {Key = 1, Name = "fanweixiao" },
3 new Customer {Key = 2, Name = "lovewangshu" }
4};
2 new Customer {Key = 1, Name = "fanweixiao" },
3 new Customer {Key = 2, Name = "lovewangshu" }
4};
i4o中对Where的扩展
1//extend the where when we are working with indexable collections!
2 public static IEnumerable<T> Where<T>
3 (
4 this IndexableCollection<T> sourceCollection,
5 Expression<Func<T, bool>> expr
6 )
7 {
8 //our indexes work from the hash values of that which is indexed, regardless of type
9 int? hashRight = null;
10 bool noIndex = true;
11 //indexes only work on equality expressions here
12 if (expr.Body.NodeType == ExpressionType.Equal)
13 {
14 //Equality is a binary expression
15 BinaryExpression binExp = (BinaryExpression)expr.Body;
16 //Get some aliases for either side
17 Expression leftSide = binExp.Left;
18 Expression rightSide = binExp.Right;
19
20 hashRight = GetHashRight(leftSide, rightSide);
21
22 //if we were able to create a hash from the right side (likely)
23 if (hashRight.HasValue && HasIndexablePropertyOnLeft<T>(leftSide,sourceCollection))
24 {
25 //cast to MemberExpression - it allows us to get the property
26 MemberExpression propExp = (MemberExpression)leftSide;
27 string property = propExp.Member.Name;
28 Dictionary<int, List<T>> myIndex =
29 sourceCollection.GetIndexByProperty(property);
30 if (myIndex.ContainsKey(hashRight.Value))
31 {
32 IEnumerable<T> sourceEnum = myIndex[hashRight.Value].AsEnumerable<T>();
33 IEnumerable<T> result = sourceEnum.Where<T>(expr.Compile());
34 foreach (T item in result)
35 yield return item;
36 }
37 noIndex = false; //we found an index, whether it had values or not is another matter
38 }
39
40 }
41 if (noIndex) //no index? just do it the normal slow way then
42 {
43 IEnumerable<T> sourceEnum = sourceCollection.AsEnumerable<T>();
44 IEnumerable<T> result = sourceEnum.Where<T>(expr.Compile());
45 foreach (T resultItem in result)
46 yield return resultItem;
47 }
48
49 }
2 public static IEnumerable<T> Where<T>
3 (
4 this IndexableCollection<T> sourceCollection,
5 Expression<Func<T, bool>> expr
6 )
7 {
8 //our indexes work from the hash values of that which is indexed, regardless of type
9 int? hashRight = null;
10 bool noIndex = true;
11 //indexes only work on equality expressions here
12 if (expr.Body.NodeType == ExpressionType.Equal)
13 {
14 //Equality is a binary expression
15 BinaryExpression binExp = (BinaryExpression)expr.Body;
16 //Get some aliases for either side
17 Expression leftSide = binExp.Left;
18 Expression rightSide = binExp.Right;
19
20 hashRight = GetHashRight(leftSide, rightSide);
21
22 //if we were able to create a hash from the right side (likely)
23 if (hashRight.HasValue && HasIndexablePropertyOnLeft<T>(leftSide,sourceCollection))
24 {
25 //cast to MemberExpression - it allows us to get the property
26 MemberExpression propExp = (MemberExpression)leftSide;
27 string property = propExp.Member.Name;
28 Dictionary<int, List<T>> myIndex =
29 sourceCollection.GetIndexByProperty(property);
30 if (myIndex.ContainsKey(hashRight.Value))
31 {
32 IEnumerable<T> sourceEnum = myIndex[hashRight.Value].AsEnumerable<T>();
33 IEnumerable<T> result = sourceEnum.Where<T>(expr.Compile());
34 foreach (T item in result)
35 yield return item;
36 }
37 noIndex = false; //we found an index, whether it had values or not is another matter
38 }
39
40 }
41 if (noIndex) //no index? just do it the normal slow way then
42 {
43 IEnumerable<T> sourceEnum = sourceCollection.AsEnumerable<T>();
44 IEnumerable<T> result = sourceEnum.Where<T>(expr.Compile());
45 foreach (T resultItem in result)
46 yield return resultItem;
47 }
48
49 }
而SLINQ则是可以让LINQ作用于streaming data上的,目前这个项目只算是个Demo版本,实现方式是为LINQ添加了一系列的扩展方法,有兴趣的朋友可以down下sourcecode来看看,需要注意的是要安装Visual Studio Orcas beta 1。
顺便帖两个codeplex上与LINQ相关的项目:
- LINQ是怎么来的?看LINQ-SQO
- 在C++/CLI上用LINQ:LINQ Extensions