Um Arquiteto de Software que se diverte pensando e escrevendo sobre princípios, práticas e padrões de design – e, eventualmente, código e desempenho de aplicações.
E, também, Microsoft MVP.
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
WhereeFirst(com predicado). O métodoWhereitera viaforeachna coleção e faz umyeld returnde 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>.MoveNextaté que seja encontrado um item que atenda ao predicado. Essa implementação é menos eficiente que a doWheree, por isso, o tempo de resposta é tão discrepante.Maluco. Né?
Abração!