score:52

Accepted answer

the enumeration in any() stops as soon as it finds a matching item as well:

https://docs.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.

score:0

although it has similar implementation, i believe any is a bit faster because it doesn't have to return an object, which in some cases may be rich, with state and behavior, depends on how well the query is thought out.

score:1

my two cents...

i had a huge performance issue with any(). i am using telerik grid to display a list of related data, ie,

-i have a "people" table

-a "company" table

-a "people_company" link table

-a "people_rol" link table

-and a "rol" table with main category, subcategory and description.

the view mixes data and has a few properties which loads data on demand about specific roles (admin, reporter, manager).

var x = getpeople().where(p => p.rols.any(i => i.uso_id == maincatid && i.tup_id == (int)roltype) && p.per_id != per_id);

var x = getpersonas().where(p => p.rols.firstordefault(i => i.uso_id == maincatid && i.tup_id == (int)roltype) != null && p.per_id != per_id);

my grid uses ajax, and takes over 10 seconds to load using "any", and 3 or less using "firstordefault". had not taken the time to debug it as requieres to intercept calls from telerik components and my model.

hope this helps... so test it well :)

score:1

we can use .count(x => x....) != 0 instead of using .any(x => x....) or .firstordefault(x => x....) != null

because query generation of linq is below,

(in any(), the 2nd(not exists) condition is not need i think.)

.any(x => x.col_1 == 'xxx')

    (@p__linq__0 varchar(8000))select 
case when ( exists (select 
    1 as [c1]
    from [dbo].[table_x] as [extent1]
    where [extent1].[col_1] = @p__linq__0
)) then cast(1 as bit) when ( not exists (select 
    1 as [c1]
    from [dbo].[table_x] as [extent2]
    where [extent2].[col_1] = @p__linq__0
)) then cast(0 as bit) end as [c1]
from  ( select 1 as x ) as [singlerowtable1]

.firstordefault(x => x.col_1 == 'xxx') != null

 (@p__linq__0 varchar(8000))select top (1) 
[extent1].[col_1] as [col_1], 
[extent1].[col_2] as [col_2], 
...
[extent1].[col_n] as [col_n]
from [dbo].[table_x] as [extent1]
where [extent1].[col_1] = @p__linq__0

.count(x => x.col_1 == 'xxx') != 0

  (@p__linq__0 varchar(8000))select 
[groupby1].[a1] as [c1]
from ( select 
    count(1) as [a1]
    from [dbo].[table_x] as [extent1]
    where [extent1].[col_1] = @p__linq__0
)  as [groupby1]

score:3

why should any continue after it has found an element satisfying the condition? if the condition applies to 1 element, that qualifies as "any".

i think they should both perform about the same, but any() does express your intention more clearly.

score:9

the problem with this question is that it is not asked within context. i am providing an answer because i see this a lot in code reviews and it bothers me. linq should not be an excuse to stop thinking.

var people = new [] { "steve", "joe" };

if (people.any(s => s == "joe"))
{
    var joe = people.first(s => s == "joe");
    // do something with joe
}

// if people is 1,000,000 people and joe is near the end do we want bigo to approach 2n here at worst case ?

var joe1n = people.firstordefault(s => s == "joe");
if (joe1n != null)
{
    // do something with joe
}

// or do we want to ensure worst case is n by simply using a variable ?

score:55

you are mixing things here. you are talking about collections, but you don't seem to use linq to objects but you are querying a database.

linq to objects:
enumerable.any and enumerable.firstordefault should perform the same, because their code is near identical:

firstordefault:

foreach (tsource source1 in source)
{
    if (predicate(source1))
        return source1;
}
return default (tsource);

any:

foreach (tsource source1 in source)
{
    if (predicate(source1))
        return true
}
return false;

linq to some database:
you are using entity framework, linq to sql or nhibernate and use queryable.any and queryable.firstordefault on the corresponding data context.
in this case, there are really no collections, because these calls are not executed on in memory objects but translated to sql.

this means, the performance difference stems from how the linq provider translates the code to sql, so the best would be to first check the statements created. are they equivalent? or are they very different (select count(0) from x vs. select top 1 from x)? then the difference might lie in the query optimizer of the db, indexes and what not...


Related Query

More Query from same tag