5

Possible Duplicate:
LINQ extension methods - Any() vs. Where() vs. Exists()

Given a list of objects in memory I ran the following two expressions:

myList.where(x => x.Name == "bla").Any() 

vs

myList.Any(x => x.Name == "bla")

The latter was fastest always, I believe this is due to the Where enumerating all items. But this also happens when there's no matches.

Im not sure of the exact WHY though. Are there any cases where this viewed performance difference wouldn't be the case, like if it was querying Nhib?

Cheers.

Community
  • 1
  • 1
clonesegg
  • 235
  • 3
  • 17
  • What tests have you run? How many iterations? What kind of differences in performance are we talking here? – eandersson May 29 '12 at 13:54
  • 1
    It shouldn't make any difference. http://stackoverflow.com/q/10110013/284240 – Tim Schmelter May 29 '12 at 13:55
  • Quick correction: I suspect you meant `==` rather than `=`. – Jon Skeet May 29 '12 at 13:56
  • Voting to close. The answers to this question provide ample insight - http://stackoverflow.com/questions/3703256/linq-extension-methods-any-vs-where-vs-exists – Robin Maben May 29 '12 at 13:59
  • SearchQueryDTO is a class with string property called Name. IList myList = new List(); for (int i = 0; i < 500; i++) { myList.Add(new SearchQueryDTO { Name = i.ToString()}); } var timer2 = Stopwatch.StartNew(); var res2 = myList.Any(x => x.Name == "499"); var time2 = timer2.Elapsed; //around .5 ms var timer = Stopwatch.StartNew(); var res = myList.Where(x => x.Name == "499").Any(); var time1 = timer.Elapsed; //around 3.5 ms – clonesegg May 29 '12 at 14:05
  • @JonSkeet he must have meant `==` as `=` would result in a compile error "cannot convert type 'string' to 'bool'". – Doctor Jones May 29 '12 at 14:05
  • @marky: I'd edit your post, don't put code in a comment unless it is **very** small snippet... – James Michael Hare May 29 '12 at 14:07
  • @TimSchmelter: I'd say it shouldn't make any *major* difference, the implementation of `Any()` with predicate and `Where()` with `Any()` have very different effects. The former simply iterates through a normal foreach loop, the latter pulls an iterator thorugh a foreach loop, which is just *slightly* less efficient. – James Michael Hare May 29 '12 at 14:09
  • @DoctaJonez: Indeed. I just didn't want to correct it silently... – Jon Skeet May 29 '12 at 14:13
  • @JamesMichaelHare: Yes, i've got the point. But it's more important to emphasize that `Where` _does **not** need to enumerate all items_ as mentioned. That's a common mistake. – Tim Schmelter May 29 '12 at 14:14
  • @TimSchmelter: absolutely agree on that point, just wasn't sure if you were saying he shouldn't be seeing a difference at all, sorry! – James Michael Hare May 29 '12 at 14:17
  • This question is not a duplicate, voting to re-open. – ataravati Sep 03 '18 at 20:09

3 Answers3

11

The Any() with the predicate can perform its task without an iterator (yield return). Using a Where() creates an iterator, which adds has a performance impact (albeit very small).

Thus, performance-wise (by a bit), you're better off using the form of Any() that takes the predicate (x => x.Name == "bla"). Which, personally, I find more readable as well...

On a side note, Where() does not necessarily enumerate over all elements, it just creates an iterator that will travel over the elements as they are requested, thus the call to Any() after the Where() will drive the iteration, which will stop at the first item it finds that matches the condition.

So the performance difference is not that Where() iterates over all the items (in linq-to-objects) because it really doesn't need to (unless, of course, it doesn't find one that satisfies it), it's that the Where() clause has to set up an iterator to walk over the elements, whereas Any() with a predicate does not.

Daniel Williams
  • 8,912
  • 15
  • 68
  • 107
James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
  • James, thanks for clearing this up for me this! I ran it a few times and was always getting this performance difference. – clonesegg May 29 '12 at 14:12
2

Assuming you correct where to Where and = to ==, I'd expect the "Any with a predicate" version to execute very slightly faster. However, I would expect the situations in which the difference was significant to be few and far between, so you should aim for readability first.

As it happens, I would normally prefer the "Any with a predicate" version in terms of readability too, so you win on both fronts - but you should really go with what you find more readable first. Measure the performance in scenarios you actually care about, and if a section of code isn't performing as you need it to, then consider micro-optimizing it - measuring at every step, of course.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

I believe this is due to the Where enumerating all items.

If myList is a collection in memory, it doesn't. The Where method uses deferred execution, so it will only enumerate as many items as needed to determine the result. In that case you would not see any significant difference between .Any(...) and .Where(...).Any().

Are there any cases where this viewed performance difference wouldn't be the case, like if it was querying Nhib?

Yes, if myList is a data source that will take the expression generated by the methods and translate to a query to run elsewhere (e.g. LINQ To SQL), you may see a difference. The code that translates the expression simply does a better job at translating one of the expressions.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005