Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FirstOrDefault is signicantly faster than SingleOrDefault while viewing ANTS profiler

Tags:

c#

linq

I have a generic collection with 5000+ items in it. All items are unique so I used SingleOrDefault to pull up an item from collection. Today I used Red Gate ANTS profiler to look into the code and found out my SingleOrDefault call has 18 millions hit for 5000 iterations with (~3.5 sec) whereas when I change it to FirstOrDefault it has 9 millions hit with (~1.5 sec).

I used SingleOrDefault because I know that all items in collection are unique.

Edit : Question will be why is FirstOrDefault faster than SingleOrDefault even though this is the exact scenario where we supposed to use SingleOrDefault.

like image 965
Myat Htut Avatar asked Jan 21 '26 18:01

Myat Htut


2 Answers

SingleOrDefault() raises an exception if there is more than one. In order to determine that, it must verify there are no more than one.

On the other hand, FirstOrDefault() can stop looking once it finds one. Therefore, I would expect it to be considerably faster in many cases.

like image 136
Jonathan Wood Avatar answered Jan 23 '26 08:01

Jonathan Wood


SingleOrDefault(predicate) makes sure there is at most one item matching the given predicate, so even if it finds a matching item near the beginning of your collection, it still has to continue to the end of the IEnumerable.

FirstOrDefault(predicate) stops as soon as it finds a matching item in the collection. If your "first matches" are uniformly distributed throughout your IEnumerable, then you will, on average, have to go through half of the IEnumerable.

For a sequence of N items, SingleOrDefault will run your predicate N times, and FirstOrDefault will run your predicate (on average) N/2 times. This explains why you see SingleOrDefault has twice as many "hits" as FirstOrDefault.

If you know you'll only ever have a single matching item because the source of your collection is controlled by you and your system, then you're probably better off using FirstOrDefault. If your collection is coming from a user for example, then it could make sense to use SingleOrDefault as a check on the user's input.

like image 39
Timothy Shields Avatar answered Jan 23 '26 08:01

Timothy Shields