Is there any difference between this:
myList.Where(item => item == 0).First();
and this:
myList.First(item => item == 0);
The later makes far more sense to me as it is shorter, but I seem to see the top version more often.
Is there any difference between this:
myList.Where(item => item == 0).First();
and this:
myList.First(item => item == 0);
The later makes far more sense to me as it is shorter, but I seem to see the top version more often.
there is no difference other than style preference
Where
does special optimizations for different kind of collection types, whereas other methods like First
, Single
and Count
do not take advantage of the type of the collection.
So Where(predicate).First()
is able to do some optimizations that First(predicate)
doesn't.
To be honest, it is bad implementation.
No, there is no difference in local queries. The Where
in the former syntax is redundant.
It depends. If the LINQ is translating to a piece of SQL then it depends on how that translation is handled. If you are using LINQ to objects (e.g. you are looking at an existing in memory array) then, while the end result in the same, the performance is markedly different. I ran some bench marks and was actually surprised at the result. I would have assumed that array.First()
would be more efficient than array.Where(...).First()
, but I found it to be the other way around.
I created a test, and to see how long it would take to traverse the array, I put the search item the last on the array. I did 200 tests of each, each test consisting of 1000 iterations. The average result, in Ticks, was:
First() = 2655969
Where().First() = 1455211
As you can see Where().First()
takes roughly about half the time of First()
alone.
My benchmarking application is as follows:
class Program
{
private const int internalIterations = 1000;
private const int externalIterations = 100;
private const int dataSize = 100000;
private const int search = dataSize - 1;
private static readonly long[] resultsFirst = new long[externalIterations*2];
private static readonly long[] resultsWhereFirst = new long[externalIterations*2];
private static readonly int[] data = Enumerable.Range(0, dataSize).ToArray();
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
for (int i = 0; i < externalIterations; i++)
{
Console.WriteLine("Iteration {0} of {1}", i+1, externalIterations);
sw.Restart();
First();
sw.Stop();
resultsFirst[i*2] = sw.ElapsedTicks;
Console.WriteLine(" First : {0}", sw.ElapsedTicks);
sw.Restart();
WhereFirst();
sw.Stop();
resultsWhereFirst[i*2] = sw.ElapsedTicks;
Console.WriteLine("WhereFirst : {0}", sw.ElapsedTicks);
sw.Restart();
WhereFirst();
sw.Stop();
resultsWhereFirst[(i*2)+1] = sw.ElapsedTicks;
Console.WriteLine("WhereFirst : {0}", sw.ElapsedTicks);
sw.Restart();
First();
sw.Stop();
resultsFirst[(i*2)+1] = sw.ElapsedTicks;
Console.WriteLine(" First : {0}", sw.ElapsedTicks);
}
Console.WriteLine("Done!");
Console.WriteLine("Averages:");
Console.WriteLine(" First Average: {0:0.00}", resultsFirst.Average());
Console.WriteLine("WhereFirst Average: {0:0.00}", resultsWhereFirst.Average());
}
private static void WhereFirst()
{
for (int i = 0; i < internalIterations; i++)
{
int item = data.Where(d => d == search).First();
}
}
private static void First()
{
for (int i = 0; i < internalIterations; i++)
{
int item = data.First(d => d == search);
}
}
}
Update
I tried using a List instead of an array as the source of the data and found that it was slower.
The data creation line looks like this:
private static readonly List<int> data = Enumerable.Range(0, dataSize).ToList();
And the end result was:
First() = 3222609
Where().First() = 2124652
"Probably not" - It may depend if the Linq query incurs translation into another language or not - SQL, for example
Functionally, they are the same, however, using .First(...)
alone may be more efficient.
.Where(item => item == 0)
will scan the entire list of items and collect all items that match the criteria into a list. Applying .First()
on that list will select the first item.
.First(item => item == 0)
has the possibility of scanning the list until it finds the first match and stopping then once it finds the first match.
So using .First(item => item == 0)
may end up being more efficient.
.First() will iterate your list until it finds your item. .Where() will iterate your whole list.
So using .First() should be more efficient. Unless if your compiler is smart enough to just do the First().