Count Property VS Count() Method

Lists: Count vs Count()

Count() is an extension method introduced by LINQ while the Count property is part of the List itself (derived from ICollection). Internally though, LINQ checks if your IEnumerable implements ICollection and if it does it uses the Count property. So at the end of the day, there's no difference which one you use for a List.

To prove my point further, here's the code from Reflector for Enumerable.Count()

public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> is2 = source as ICollection<TSource>;
if (is2 != null)
{
return is2.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}

Count property vs Count() method?

Decompiling the source for the Count() extension method reveals that it tests whether the object is an ICollection (generic or otherwise) and if so simply returns the underlying Count property:

So, if your code accesses Count instead of calling Count(), you can bypass the type checking - a theoretical performance benefit but I doubt it would be a noticeable one!

// System.Linq.Enumerable
public static int Count<TSource>(this IEnumerable<TSource> source)
{
checked
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
ICollection<TSource> collection = source as ICollection<TSource>;
if (collection != null)
{
return collection.Count;
}
ICollection collection2 = source as ICollection;
if (collection2 != null)
{
return collection2.Count;
}
int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
num++;
}
}
return num;
}
}

Enumerable.Count() vs property Count

How about looking in the source code.

On line 1905 you can see the count method with the following lines:

ICollection<TSource> collectionoft = source as ICollection<TSource>;
if (collectionoft != null) return collectionoft.Count;
ICollection collection = source as ICollection;
if (collection != null) return collection.Count;

As you can see, the method uses the ICollection.Count propertie, when the IEnumerable is a ICollection.

Take in account, the following method with the signature Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) does not implement this (because of the custom count method you provide ; ) )

EDIT:

It should also be mentioned, that the LongCount methods do not use this property.

Because of all this, there is no need to implement your own Count().

When should I use .Count() and .Count in the context of an IEnumerableT

The extension method works on any IEnumerable<T> but it is costly because it counts the sequence by iterating it. There is an optimization if the sequence is ICollection<T> meaning that the length of the collection is known. Then the Count property is used but that is an implementation detail.

The best advice is to use the Count property if available for performance reasons.

Is .Count() predominately better saved for queryable collections that are yet to be executed, and therefore don't have an enumeration yet?

If your collection is IQueryable<T> and not IEnumerable<T> then the query provider may be able to return the count in some efficient maner. In that case you will not suffer a performance penalty but it depends on the query provider.

An IQueryable<T> will not have a Count property so there is no choice between using the extension method and the property. However, if you query provider does not provide an efficient way of computing Count() you might consider using .ToList() to pull the collection to the client side. It really depends on how you intend to use it.

Size property vs Count() method in ArrayList - Kotlin

I agree with Alex.T in the comments, the problem is probably with your measurement method, rather than a discrepancy with the code you're measuring.

Here's a version where we run the algorithm 10 million times, which should hopefully account for any unrelated differences affected by what's going on in the JVM/System.

Result:

Average time taken for filter count call: 97
Average time taken for filter size call: 99

There doesn't seem to be much in it (which makes sense, since count() is inlined to size by the compiler, so they are executing the same code).

Code:

import kotlin.system.measureNanoTime

fun main() {
val nums = listOf(4, 5, 3, 2, 1, -1, 7, 6, -8, 9, -12)
val (filterCount, filterSize) = anshulBenchmark(nums)
println("Average time taken for filter count call: $filterCount")
println("Average time taken for filter size call: $filterSize")
}

fun anshulBenchmark(nums: List<Int>, iterations: Int = 10_000_000): Pair<Long, Long> {
var filterCount = 0L
var filterSize = 0L
repeat(iterations) {
filterCount += measureNanoTime { nums.filter { e -> e > 0 }.count() }
filterSize += measureNanoTime { nums.filter { e -> e > 0 }.size }
}
return Pair(filterCount / iterations, filterSize / iterations)
}

In .NET, is it better to call .Count() or, when available, .Count?

My personal preference is to stick with the existing methods and properties if they are available without casting. Therefore I'd use Count.

Which method performs better: .Any() vs .Count() 0?

If you are starting with something that has a .Length or .Count (such as ICollection<T>, IList<T>, List<T>, etc) - then this will be the fastest option, since it doesn't need to go through the GetEnumerator()/MoveNext()/Dispose() sequence required by Any() to check for a non-empty IEnumerable<T> sequence.

For just IEnumerable<T>, then Any() will generally be quicker, as it only has to look at one iteration. However, note that the LINQ-to-Objects implementation of Count() does check for ICollection<T> (using .Count as an optimisation) - so if your underlying data-source is directly a list/collection, there won't be a huge difference. Don't ask me why it doesn't use the non-generic ICollection...

Of course, if you have used LINQ to filter it etc (Where etc), you will have an iterator-block based sequence, and so this ICollection<T> optimisation is useless.

In general with IEnumerable<T> : stick with Any() ;-p

Which i should use Any() or Count() ? And which one is faster? Will both return same output(True or false) if any data exists in IEnumerable object?

Any will be faster because (in your case IEnumerable <object>) it returns true as soon as first element matching your condition is found.

Whereas Count has to go till the end of the collection (read iterate collection) to get its result.

Food4Thought:

1. Yours will throw exception because collection is null.

2. object1.Where (s => s.IsActive); will show compile time exception on s.IsActive because collection is of object type and IsActive is not a property in object class. Change it to IEnumerable<My_Class_Which_Have_Is_Active_Property>.

Does .Where(x= x.listFoos.Count() 1) count all sub element?

It won't count anything. List<T> redundantly stores the number of elements, so accessing the Count property is a O(1) operation.

This works even if you use the Enumerable.Count() extension method rather than List<T>s built-in Count property, because Enumerable.Count() has a built-in optimization if the underlying data source implements ICollection<T>.


As mentioned by Enigmativity in the comments: If you have an IEnumerable which is not an ICollection<T>, you can use the following instead to prevent iterating the entire enumerable:

var result = input.Where(x => x.Foos.Skip(1).Any()).ToList();


Related Topics



Leave a reply



Submit