LINQ, Where() vs FindAll()

C#LinqSyntax

C# Problem Overview


Can someone explain how the LINQ functions Where(..) and FindAll(..) differ? They both seem to do the same thing...

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

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.

Solution 5 - C#

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();
		}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGrantView Question on Stackoverflow
Solution 1 - C#Adam RobinsonView Answer on Stackoverflow
Solution 2 - C#cfernView Answer on Stackoverflow
Solution 3 - C#WayneCView Answer on Stackoverflow
Solution 4 - C#digibenView Answer on Stackoverflow
Solution 5 - C#Adebayo VicktorView Answer on Stackoverflow