2011-11-02 20 views
5

Let decir que tengo¿Seleccionar seguido por Donde resulta en dos iteraciones sobre IEnumerable?

IEnumerable<int> list = new int[] { 1, 2, 3 }; 
List<int> filtered = list.Select(item => item * 10).Where(item => item < 20).ToList(); 

La pregunta es ¿Hay dos iteraciones o sólo uno.

En otras palabras, es que un rendimiento equivalente a:

IEnumerable<int> list = new int[] { 1, 2, 3 }; 
List<int> filtered = new List<int>(); 
foreach(int item in list) { 
    int newItem = item * 10; 
    if(newItem < 20) 
     filtered.Add(newItem); 
} 

Respuesta

7

Hay una sola iteración sobre la colección lleva a cabo cuando se llama al método .ToArray por lo tanto deben ser equivalentes. .Select es una proyección y .Where es un filtro, ambos expresados ​​como árboles de expresión en el conjunto de datos original.

podría ser fácilmente comprobado:

public class Foo: IEnumerable<int> 
{ 
    public IEnumerator<int> GetEnumerator() 
    { 
     yield return 1; 
     Console.WriteLine("we are at element 1"); 
     yield return 2; 
     Console.WriteLine("we are at element 2"); 
     yield return 3; 
     Console.WriteLine("we are at element 3"); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
     var filtered = new Foo() 
      .Select(item => item * 10) 
      .Where(item => item < 20) 
      .ToList(); 
    } 
} 

cuando se imprime ejecute el siguiente:

we are at element 1 
we are at element 2 
we are at element 3 
+0

Un pequeño nitpick: La pregunta está etiquetada como "linq-to-objects", por lo que no hay árboles de expresión implicados, solo iteración directa a través de la secuencia junto con invocaciones de delegado. – LukeH

2

en LINQ a Objetos WHERE y seleccione No iterar sobre la enumerable. El código de llamada lo enumera cuando hace un foreach en la consulta o ToList o ToArray(), etc.

En Linq to SQL no hay iteración alguna vez. Cuando haces ToList o ToArray() la consulta se ejecuta por la base de datos. Dependiendo del tipo de consulta, db podría buscar índices o hacer un escaneo de tabla.

Cuestiones relacionadas