Performance of Linq Any VS Firstordefault != Null

Performance of LINQ Any vs FirstOrDefault != null

The enumeration in Any() stops as soon as it finds a matching item as well:

https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any

I would expect the performance to be very similar. Note that the FirstOrDefault version won't work with a collection of value types (since the default isn't null) but the Any version would.

FirstOrDefault(), SingleOrDefault(), Any(), etc... Which One Is The Fastest?

If you have a think about this you can probably work it out.

FirstOrDefault enumerates the set until it finds a matching item

SingleOrDefault enumerates the entire collection to ensure the item occurs exactly once

This means SingleOrDefault cant be faster than FirstOrDefault. But it does depend a little on the query providers implementation

EDIT:

Any can be implemented even faster. Concider a SQL implementation:

Select Top 1 from myTable //(its not quite this but this implementation but it will be similar)

will execute faster than:

Select Top 1 from myTable where <somecondition>

LINQ ANY() with First() And FirstOrDefault()

You can use the null-conditional operator to make all of this a lot simpler, assuming that the element type of totals is a reference type:

TotalCashIn = totals?.FirstOrDefault()?.TotalCashIn;

With this:

  • If totals is null, the overall result is null due to the first null-conditonal operator
  • If totals is empty, FirstOrDefault() will return null, so the overall result is null due to the second null-conditional operator
  • Otherwise, the result is the TotalCashIn property of the first element

Is there any difference in performance between these two LINQ to SQL queries?

I'm not sure what GetAll() does. If it moves all items from your database to your local memory, then I wouldn't bother: try to improve that statement. Why fetch all items if you only need the first one.

If GetAll() returns an IQueryable<...>, then there is a slight difference:

FirstOrDefault() will change the Expression in the query, such that the SQL statement will be Select top 1 ... from.

After changing the expression it will ask the Provider of the IQqueryable to execute the Expression, the complete result of the SQL statement will b transferred to local memory, which in this case will be one item.

Any() will almost do the same, except that the SQL will be: Select top 1 1 from ...

It is easy to see that a Select top 1 1 will at utmost transfer one integer, while Select top 1 will transfer all selected columns.

Hence, if you only want to check if there are any elements, Any() is more efficient then FirstOrDefault

Check for null after FirstOrDefault?

It could be rewritten, in various ways, as:

The key is: use Where

var result = protsDict.Where(somePredicate).SomeLinqChain(...) //some chain
.Where(someMore) //some more
.Where(i => i.Value != null) //or even...
.Select(i =>i.Value.SomeProps).FirstOrDefault();//then select; take or skip


Related Topics



Leave a reply



Submit