开发者

LINQ, Where() vs FindAll()

Can someone explain how the开发者_Python百科 LINQ functions Where(..) and FindAll(..) differ? They both seem to do the same thing...


FindAll() is a function on the List<T> type, it's not a LINQ extension method like Where. The LINQ extension methods work on any type that implements IEnumerable, whereas FindAll can only be used on List<T> instances (or instances of classes that inherit from it, of course).

Additionally, they differ in actual purpose. Where returns an instance of IEnumerable that is executed on-demand when the object is enumerated. FindAll returns a new List<T> that contains the requested elements. FindAll is more like calling Where(...).ToList() on an instance of IEnumerable.


The biggest difference to me is that .FindAll is also available in .Net 2.0. I don't always have the luxury to program in .Net 3.5, so I try to remember the 'native' methods of the .Net generic collections.

It happened several times that I implemented an already available List method myself because I couldn't LINQ it.

What I find handy in this case is that, using VS2008, I can use type inference and the lambda syntax. These are compiler features, not framework features. This means I can write this and still remain within .Net 2.0:

var myOddNums = myNums.FindAll(n => n%2==1);

But if you do have LINQ available, keeping the difference between deferred execution and immediate execution is important.


If I recall correctly, the main difference (besides what they're implemented on: IEnumerable<T> vs. List<T>) is that Where implements deferred execution, where it doesn't actually do the lookup until you need it -- using it in a foreach loop for example. FindAll is an immediate execution method.


I did some tests on a list of 80K objects and found that Find() can be up to 1000% faster than using a Where with FirstOrDefault(). I didn't know that until testing a timer before and after each call. Sometimes it was the same time, other times it was faster.


Performance wise FindAll() is better, Here is an example below. The FindAll takes 3millisecs while the Where took 11millisecs.

    public class SortedSearch
    {
        public static int[] CountNumbersUsingFindAll(int[] sortedArray, int lessThan)
        {
            var smaller = Array.FindAll(sortedArray,x => x < lessThan);
            return smaller;
        }
        public static IEnumerable<int> CountNumbersUsingWhere(int[] sortedArray,int lessThan)
        {
            var smaller = sortedArray.Where(x => x < lessThan);
            return smaller;
        }
   }

class Program
{
        static void Main(string[] args)
        {
            Stopwatch s = Stopwatch.StartNew();
            Console.WriteLine(SortedSearch.CountNumbersUsingFindAll(new int[]{1,3,5,7},4));
            Console.WriteLine(s.ElapsedMilliseconds);
            s.Stop();

            s.Restart();
            Console.WriteLine(SortedSearch.CountNumbersUsingWhere(new int[] { 1, 3, 5, 7 }, 4));
            Console.WriteLine(s.ElapsedMilliseconds);
            s.Stop();
            Console.ReadKey();
        }
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜