Um Arquiteto de Software que se diverte pensando e escrevendo sobre padrões e práticas de design – e, eventualmente, código e desempenho de aplicações.
A diferença está na implementação dos métodos Where e First (com predicado). O método Where itera via foreach na coleção e faz um yeld return de cada item que corresponda ao predicado. Essa implementação é rápida porque é traduzida pelo compilador como um for, já que numbers é um array, e, em seguida, o método First (sem predicado) apenas retorna o primeiro item do IEnumerator<T> obtido junto à coleção.
Já no caso do método First (com predicado), a implementação é diferente: há uma tentativa de converter a coleção para um IList<T> e, sendo possível, é retornado o primeiro item da lista. Não sendo possível, ou seja, se a coleção não implementa IList<T>, é obtido um IEnumerator<T> da coleção via GetEnumerator, e então ocorre a iteração pela coleção via IEnumerator<T>.MoveNext até que seja encontrado um item que atenda ao predicado. Essa implementação é menos eficiente que a do Where e, por isso, o tempo de resposta é tão discrepante.
Maluco. Né?
Abração!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Muito legal! Agora, fiquei surpreso com o resultado, imaginava que o tempo do First e Where.First seriam próximos. Qual é o motivo da diferença?
Fala, Rafa! Tudo bom?
Gostou da pegadinha. Né? rs
A diferença está na implementação dos métodos
Where
eFirst
(com predicado). O métodoWhere
itera viaforeach
na coleção e faz umyeld return
de cada item que corresponda ao predicado. Essa implementação é rápida porque é traduzida pelo compilador como umfor
, já quenumbers
é um array, e, em seguida, o métodoFirst
(sem predicado) apenas retorna o primeiro item doIEnumerator<T>
obtido junto à coleção.Já no caso do método
First
(com predicado), a implementação é diferente: há uma tentativa de converter a coleção para umIList<T>
e, sendo possível, é retornado o primeiro item da lista. Não sendo possível, ou seja, se a coleção não implementaIList<T>
, é obtido umIEnumerator<T>
da coleção viaGetEnumerator
, e então ocorre a iteração pela coleção viaIEnumerator<T>.MoveNext
até que seja encontrado um item que atenda ao predicado. Essa implementação é menos eficiente que a doWhere
e, por isso, o tempo de resposta é tão discrepante.Maluco. Né?
Abração!