2010-07-19 16 views

Respuesta

4

No, es O (n). Todos los métodos de extensión en IEnumerable<T> son, por necesidad, O (n) (porque lo único que puede hacer IEnumerable<T> es ... enumerar). Aunque, como se señala en los comentarios, intentan enviar a una interfaz que puede implementar la operación más rápido (por ejemplo, ElementAt intentará convertir a IList<T> para implementar una operación O (1)). No es que eso ayude en el caso de HashSet<T> que no implementa IList<T> de todos modos.

Para HashSet<T> el concepto de "ElementAt" no tiene mucho sentido de todos modos, porque no hay una "orden" como tal. Básicamente, estás obteniendo un elemento aleatorio.

+0

Entonces, una cosa más inteligente sería hacer un 'ToArray' si necesita usar ElementAt en muchas filas? ¿Nunca es posible obtener el pedido "correcto" con un HasSet? –

+2

Sí, un solo 'ToArray' y luego múltiples" elemento en "(a través del operador' [] ') sería mucho más rápido. No existe un orden "correcto" con un HashSet, ya que los elementos no están ordenados de ninguna manera significativa. –

+0

Derecha, sin embargo, cuando hago esto: {2, 3, 4} e inicio dos HashSets con esos, obtengo el orden correcto al recorrer cada elemento. –

2

No hay método en el ElementAtHashSet por lo que probablemente quieren saber el rendimiento del método Enumerable.ElementAt cuando se usa en una instancia de HashSet<T>.

El método Enumerable.ElementAt tiene una optimización para los tipos que implementan IList<T>. En ese caso, el rendimiento es O (1). Sin embargo, HashSet no implementa esta interfaz, por lo tanto, el rendimiento es O (n).

+0

@Steven, hay un elemento porque HashSet deriva de ICollection. –

+0

@Filip: 'HashSet ' deriva de 'ICollection ', pero 'ICollection ' no tiene un método 'ElementAt'. 'HashSet ' no (al menos en .NET 3.5sp1) contiene un método 'ElementAt'. – Steven

+0

@Steven, estoy usando .NET 4.0 y ReSharper me sugiere que use 'ICollection ' donde quiero tomar 'HashSet '. De todos modos, usar 'ToArray' aceleró mucho las cosas. –

2

Depende del tipo de lista de subllantas. El reflector muestra que Enumerable<T>.ElementAt(...) intenta convertir primero a IList<T>. En ese caso sería O (1).

Un proveedor de consultas, por ejemplo, puede devolver algo que es un IList<T>. Pero lo más probable es que si aplica cualquiera de los operadores de Linq, se convertirá en IEnumerable<T>, ya que se construyen simplemente utilizando diferentes enumeradores, y se convertirá en O (n).

EDITAR: He leído el HashSet. Un HashSet<T> no implementa IList<T>, por lo tanto, es O (n).

Cuestiones relacionadas