terça-feira, 5 de fevereiro de 2013

C# - Yield Return

Yield return é um comando que pouca gente conhece e menos ainda o utiliza, porém em alguns casos, nos ajuda e muito.
Yield return utiliza lazy-load, ou seja, carregar aos poucos.
A sintaxe do yield é muito simples:
RecuperarSerieFibonacci
Neste exemplo, temos um método que retorna a série de fibonacci (1,1,2,3,5,8...). Se prestarmos atenção no código, podemos perceber que ele não tem uma condição de parada, o que nos levaria a pensar que a execução do mesmo nunca sairia do loop, porém ai que entra o "carregar aos poucos".
Quando chamamos o método RecuperarSerieFibonacci, o valor da série só será carregado quando pedirmos, por exemplo: RecuperarSerieFibonacci().Take(10).ToList() iria processar os 10 primeiros números da série de fibonacci.
Bom, mas poderiamos fazer o mesmo sem utilizar a série de fibonacci, certo? Então qual a vantagem?
Criei um outro exemplo onde precisamos descobrir o índice de uma palavra dentro de um arquivo de texto, então, para simular o problema, criei um arquivo com cerca de 30 mil linhas e coloquei 3 palavras que deveriam ser encontradas:
1. inconstitucionalissimamente (no inicío do arquivo, proximo da linha de número 10)
2. paralelepipedo (na metade do arquivo, proximo da linha de número 15 mil)
3. pneumonia (no final do arquivo, proximo da linha de número 30 mil)
Criei também 2 métodos para retornar cada uma das palavras de cada linha do arquivo, um utilizando yield return e o outro não.
Por fim, chamei os métodos procurando cada uma das palavras, obtendo o seguinte resultado:
Resultado Analisador
Como pudemos observar, em todos os casos, obtivemos um melhor resultado quando utilizamos o yield return, isso ocorreu pelos seguintes motivos:
1. Quando procuramos as palavras que estavam no inicio ou no meio do arquivo, quando não utilizamos o yield return, todo o arquivo era lido e separado por palavras para depois a palavra ser procurada, já quando utilizamos o yield return, o arquivo era lido a cada linha, fazendo com que o arquivo não precisasse ser lido por completo, economizando tempo de leitura.
2. No caso da terceira palavra, como a mesma estava no final do arquivo, então porque ainda assim a performance foi melhor? Isso ocorre pois utilizando o yield return, os valores retornados pela função não foram armazenados em memória da forma como construímos a busca.

Muito bom não?

Abaixo estou disponibilizando as classes utilizadas. O arquivo de texto utilizado para a busca só pode ser encontrado através do download do código fonte no link (source) ou fazendo download através do git em:
https://github.com/fsaalmeidinha/yieldreturn.git

FileTexthelper.cs
Analisador.cs

3 comentários: