5

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.

Cheetah
  • 13,785
  • 31
  • 106
  • 190
  • The Where is redundant and if you have ReSharper installed, it will suggest you the second form. – Pierre-Luc Pineault Jun 06 '13 at 13:59
  • Thanks @Pierre-LucPineault ...seems someone is now saying using the later is more efficient...I can understand the reasoning, but everyone else says there is no difference! – Cheetah Jun 06 '13 at 14:04
  • you can do your own benchmarks if you want to test the efficiency. Get a huge list of items, call both methods millions of times and compare the execution time. – Pierre-Luc Pineault Jun 06 '13 at 14:07
  • 7
    See [Why is LINQ .Where(predicate).First() faster than .First(predicate)?](http://stackoverflow.com/q/8663897/9664) – Metro Smurf Jun 06 '13 at 14:08

7 Answers7

5

there is no difference other than style preference

Jason Meckley
  • 7,589
  • 1
  • 24
  • 45
  • Yes there is a small performance difference, but not one that will drastically impact a majority of implementation scenarios. This would only play out in edge cases. Still good information to understand how things work. – Jason Meckley Jun 06 '13 at 17:19
4

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.

manojlds
  • 290,304
  • 63
  • 469
  • 417
3

No, there is no difference in local queries. The Where in the former syntax is redundant.

Rotem
  • 21,452
  • 6
  • 62
  • 109
3

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
Colin Mackay
  • 18,736
  • 7
  • 61
  • 88
2

"Probably not" - It may depend if the Linq query incurs translation into another language or not - SQL, for example

Dave Bish
  • 19,263
  • 7
  • 46
  • 63
-3

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.

Matt Houser
  • 33,983
  • 6
  • 70
  • 88
  • that is not correct. linq uses enumerations and deferred execution. so where(x).first() and first(x) will process the same number of items until 1 is found – Jason Meckley Jun 06 '13 at 14:08
  • "may end up being more efficient" is rather suggestive. Run some benchmarks and you may be surprised. – Metro Smurf Jun 06 '13 at 14:09
  • As mentioned above, [.Where(...).First() is faster than just .First(...)](http://stackoverflow.com/questions/8663897/why-is-linq-wherepredicate-first-faster-than-firstpredicate). Wow. – Matt Houser Jun 06 '13 at 14:27
  • The only time it "collect[s] all items that match the criteria into a list" is if you put `.ToList()` on the end. – Colin Mackay Jun 06 '13 at 14:29
-5

.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().

Carra
  • 17,808
  • 7
  • 62
  • 75