Определение, приведет ли вызов к счету ICollection к итерации - PullRequest
1 голос
/ 03 мая 2011

Предположим, я хочу получить доступ к объекту из Collection, и я хочу быть уверен он не перебирает все Collection только для определения размера.

Как я могу определить и проконтролировать, приведет ли вызов к Count к действительной итерации по коллекции? (кроме использования моей собственной реализации ICollection), другими словами, есть ли реализации, которые предлагают это?

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);
    }
}

В ответ на вопрос героя программистов. Я полагаю, что я могу сделать коллекцию IEnumerable<T>, добавить к ней миллион документов и посчитать ее, чтобы увидеть, насколько быстрым является и вызов Count.

Я задал этот вопрос, поскольку я могу выбрать использование IEnumerable вместо Collection, поскольку мои коллекции так же велики по количеству и данным на элемент, что будет проблемой вернуть их все сразу.

Однако я хотел бы знать и недостатки IEnumarable, Джошуа указал на блокировку, что это не очень хорошая идея, в другом вопросе.

Ответы [ 3 ]

2 голосов
/ 03 мая 2011

Существуют ли реализации Count, которые относительно дороги?Возможно, но они будут редкими;классы .NET Framework настроены на довольно хорошую всестороннюю эффективность.

Имеет ли это значение?Почти наверняка нет.Если вы не запрашиваете Count миллионы раз по коллекциям с миллионами элементов, разница настолько мала, что не имеет значения:

  • 100 миллионов вызовов List<T>.Count, содержащих 1 миллион целых чисел: 0,85с
  • 100 миллионов вызовов HashSet<T>.Count(), содержащих 1 миллион целых чисел: 1,45 с
1 голос
/ 03 мая 2011

Поскольку ICollection выставляет Count как свойство, можно с уверенностью предположить, что его значение очень дешево получить (т. Е. Оно не должно выполнять итерацию всей коллекции).

Это просто лучшая практика в отношении свойств - получение их значений должно быть дешевым - точка.

Если операция дорогая, то это должен быть метод, например Count ().

Конечно, кто-то может предоставить дорогостоящую реализацию ICollection.Count - однако тогда этот человек не делает все правильно.

Если подсчет количества элементов стоит дорого, они должны реализовывать только IEnumerable, а не ICollection.

0 голосов
/ 03 мая 2011

Технически, поскольку ICollection является интерфейсом, у вас нет гарантии, что он не будет проходить по коллекции.Интерфейс может быть реализован в любом случае.

...