Question

Suppose I want to access an object from a Collection, and I want to be sure it doesn't iterate through the whole Collection just to determine the size.

How can I determine and control if a call to Count results in actually iterating though the collection? (other than using my own implementation of ICollection) , in other words are there implementations that offer this?

public void PrintThreeNames(ICollection<string> names)
{
    //first I want to know if the collection has at least three elements.
    if (names != null && names.Count >= 3)
    {
        IEnumerator<string> enumerator = names.GetEnumerator();
        string value0 = enumerator.Current;
        enumerator.MoveNext();
        string value1 = enumerator.Current;
        enumerator.MoveNext();
        string value2 = enumerator.Current;
        //print values.
        Console.Writeline(value0 + value1 + value2);
    }
}

In response to the programmers hero question. I guess I can make a IEnumerable<T> collection add a million documents to it, and count it to see how fast a call to Count is as well.

I asked this question as I may choose using IEnumerable over Collection, as my collections are so large in numbers and data per item as well, that it will be a problem to return all of them at once.

However, I would like to know the disadvantages of IEnumarable as well, Joshua pointed about locking it is not a good idea, in another question.

Was it helpful?

Solution

Because ICollection exposes Count as a property, it should be safe to assume that it is very cheap to get its value (i.e. it should not iterate through the entire collection).

This is just a best practice surrounding properties - getting their values should be cheap - period.

If the operation is expensive, then it should be a method - e.g. Count().

Sure, somebody could certainly provide an expensive implementation of ICollection.Count - however then that person is not doing things right.

If calculating the number of elements is expensive, they should implement only IEnumerable - not ICollection.

OTHER TIPS

Are there implementations of Count that are relatively expensive? Probably, but they'll be rare; the .NET Framework classes are tuned for pretty good all-round efficiency.

Does it matter? Almost certainly not. Unless you're querying Count millions of times over collections with millions of elements, the difference is so small as to be irrelevant:

  • 100 Million calls to List<T>.Count containing 1 million integers: 0.85s
  • 100 Million calls to HashSet<T>.Count() containing 1 million integers: 1.45s

Technically because ICollection is an interface you have no guarantee that it won't iterate through the collection. The interface could be implemented anyway.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top