Понимание дополнительного ElementAt (индекс)

Рассмотрите этот код:

int size = 100 * 1000 * 1000;
var emu = Enumerable.Range(0, size);
var arr = Enumerable.Range(0, size).ToArray();

когда я называю страуса эму. ElementAt (размер 10) и прибытие. ElementAt (размер 10) и мера время, прибытие намного быстрее (массив составляет 0,0002 с по сравнению с IEnumerable 0,59 с).

Насколько я понимаю метод расширения ElementAt () имеет подпись

public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)

и так как 'источник' является IEnumerable, выполненная логика была бы подобна - настроенный против того, что я вижу, где к массиву получают доступ непосредственно.

Мог кто-то объяснять это :)

5
задан Cœur 26 February 2017 в 02:43
поделиться

2 ответа

Это оптимизация, выполняемая на этапе выполнения. Хотя вызов не перегружен, он способен проверить (используя is или as), действительно ли источник является IList. Если да, то он может перейти непосредственно к нужному элементу.

Это делают и другие вызовы - в частности, Count(), который оптимизирован для ICollection и (начиная с .NET 4) негенерического интерфейса ICollection.

Одним из недостатков методов расширения является то, что все эти оптимизации должны выполняться самой реализацией - типы не могут переопределить что-либо, чтобы "отказаться" от оптимизации методов расширения. Это означает, что все оптимизации должны быть известны оригинальному реализатору :(

5
ответ дан 18 December 2019 в 09:47
поделиться

Вызов ElementAt в IEnumerable будет перебирать элементы до тех пор, пока не будет достигнут желаемый индекс. (Операция O (n))

Вызов ElementAt в IList (например, массив) будет использовать IList индексатор, чтобы сразу получить желаемый индекс.(Операция O (1))

12
ответ дан 18 December 2019 в 09:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: