2010-06-04 15 views
25

Me preguntaba qué tipo tendría un mejor rendimiento y cuál crees que debería usarse.¿Qué es mejor usar array o List <>?

Por ejemplo, tengo una Lista de cadenas sin saber cuántos elementos necesitaré, por lo que tener la función .Add (Cadena) es realmente conveniente. Puedo agregar nuevas cadenas a la lista en cualquier momento fácilmente.

¿Cuáles son las ventajas/desventajas de usar cada uno?

¿Enumera las nuevas matrices?

+1

@Evan: La segunda parte de tu comentario es muy engañosa. Puede inicializar una 'Lista ' con una capacidad específica de la misma manera que lo hace con una matriz. Si conoce el tamaño por adelantado, no importa cuál use, y si no conoce el tamaño por adelantado ** como la pregunta lo dice claramente **, entonces * no puede * usar una matriz . Si tiene pruebas de que las matrices ofrecen un rendimiento de lectura "mucho" mejor, publique una respuesta con esa evidencia. – Aaronaught

Respuesta

36

Más contexto es realmente necesario para responder a la pregunta correctamente:

En una API pública, usted debe tratar de utilizar los tipos abstractos de recolección, por lo que puede cambiar la implementación interna más tarde si es necesario.

  • Si la colección no debe ser cambiada por el mundo exterior, use IEnumerable<T>.
  • Si la colección será cambiada por el mundo exterior, use ICollection<T>.
  • Si se requiere acceso indizado, use IList<T>.

En una implementación privada, que no es tan importante la utilización de los tipos abstractos:

  • Si necesita acceso indexado y conocer el tamaño final, utilice T[] o List<T>.
  • Si necesita acceso indexado y no conoce el tamaño final, use List<T>.
  • Si va a acceder a los elementos en un patrón LIFO, use Stack<T>.
  • Si va a acceder a los elementos en un patrón FIFO, use Queue<T>.
  • Si necesita acceder a los elementos al principio y al final de la lista, pero no en el medio, use LinkedList<T>.
  • Si no desea duplicados, use HashSet<T>.

En .NET 4.0 tiene algunas opciones más, pero esos son los conceptos básicos.

+0

"Si la colección no debe ser cambiada por el mundo exterior use IEnumerable " - No estoy de acuerdo con esta caracterización.Devolver IEnumerable no ayudará si el objeto al que hace referencia el valor devuelto es una lista mutable: la persona que llama siempre puede emitir. Debe devolver IEnumerable si la persona que llama solo debe poder enumerar, ICollection si también necesita un conteo, e IList si necesita acceso indexado. En ** todos ** de los casos anteriores, si la colección no debe ser cambiada por el mundo exterior, envuélvala en una colección de solo lectura (por ejemplo, usando la lista .AsReadOnly). – Joe

+1

@Joe: No soy un fanático de ese argumento. La persona que llama siempre puede intentar emitir ** cualquier cosa ** que le dé * cualquier cosa * else - simplemente es un diseño deficiente para hacerlo. Puede envolver todos los resultados en un 'ReadOnlyCollection ' si lo desea, pero eso no lo protegerá contra las personas que llaman * hostile *; solo pueden usar Reflection para acceder a la lista mutable interna. Si se trata de un código ultraseguro, entonces la única forma de garantizar este invariante particular es devolver un * nuevo *, instancia 'IEnumerable ' generada, es decir, devolviendo' originalEnumerable.Select (x => x) .ToArray() '. – Aaronaught

+0

Pero en cualquier caso, las recomendaciones son desde una perspectiva de descubrimiento y mantenimiento del código (escritura de código de auto-documentación), no desde una perspectiva de seguridad; si estás en el último campamento, entonces tienes * muchas * otras cosas de qué preocuparse. También es la razón por la que utilicé la frase "no debería" en lugar de "no debo": no es una garantía, solo una pista muy fuerte. 'ReadOnlyCollection ' dará un error * runtime * si se intenta una modificación; Desea detectar dichos errores en * compile-time * siempre que sea posible. – Aaronaught

22

List<String> se implementa utilizando una matriz String[].

Si usted no sabe cuántos elementos que tendrá, utilice List<String>

le puede dar el número estimado (o máximo) de elementos que espera en el parámetro constructor de capacidad (new List<String>(10)), éste será el tamaño inicial de la matriz subyacente.

Cuando Add() hay un elemento y no hay espacio para este artículo, la matriz subyacente se copia a una nueva matriz del doble del tamaño.

Lo que hago: cuando sé el tamaño exacto de la colección y sé que no cambiaré el tamaño de la colección, utilizo una matriz (String[]). De lo contrario, uso un List<String>.

Por cierto, esto va para cualquier tipo y no solo String.

+0

+1. por mencionar la capacidad inicial de la lista. –

+0

ídem. Buena lógica del "mundo real" –

+0

+1 por ser la mejor respuesta, pero solo va a mitad de camino para comparar las diferencias. [Interpretación de lectura] Para matrices, el valor si un índice puede recuperarse inmediatamente porque el desplazamiento es estático, mientras que con las listas, los elementos deben rastrearse para obtener el valor de un índice. Para colecciones grandes, esto puede tener un impacto drástico en el rendimiento. [Escribir rendimiento] Por el contrario, las listas pueden crecer indefinidamente sin tener que mover datos. Con una matriz, necesita asignar una nueva matriz y copiar la memoria en ella (realmente ineficiente). Las transmisiones de memoria son la respuesta a las matrices en crecimiento. –

7

Depende del escenario de uso, PERO también es una micro-optimización hasta que haya identificado un cuello de botella mediante el perfil. Use lo que mejor se adapte al uso.

2

Si no conoce el tamaño de los elementos que se agregarán, siempre vaya a List<string> que la matriz de cadenas.

2

Si necesita un tamaño dinámico, entonces vaya con List<string>.

Si le preocupa el rendimiento, le sugiero que comience con List<string> y vea si realmente hay un problema. Utiliza matrices internamente, por lo que creo que, en su mayor parte, no debería haber problemas de rendimiento.

Si tiene una colección de tamaño estático, aún puede usar string[].

2

Por supuesto que depende de su aplicación, pero en circunstancias List<string> (o incluso sólo IEnumerable<string> es preferible.

3

Usar lista <> en la mayoría de los casos, y no se preocupe por el rendimiento. Hay una buena probabilidad pasarás por toda tu carrera y nunca necesitarás la melodía de interpretación convirtiendo una lista <> en una matriz

3

En la mayoría de los escenarios, la diferencia de rendimiento no es apreciable, así que usaría List<string> ya que proporciona mucha más funcionalidad que podría ser útil en diferentes situaciones.

Cuestiones relacionadas