2011-01-18 6 views
9

Estoy tratando de determinar cuándo es más eficiente que List<T>.Add() en comparación con el método Array.Resize().¿Qué es más eficiente: Lista <T> .Add() o System.Array.Resize()?

La documentación para Array.Resize dice que tiene una copia de toda la matriz, y lo coloca en un nuevo objeto. El viejo objeto debería ser descartado. ¿Dónde reside este viejo objeto? En la pila o el montón?

No sé cómo funciona List.Add().

¿Alguien sabe cómo el método List.Add se compara con el método estático Array.Resize?

estoy interesado en el uso de memoria (y limpieza), y lo que es mejor para los 300 tipos de valor, en comparación con 20.000 tipos de valor.

Por lo que vale la pena, estoy planeando sobre la ejecución de este código en uno de los sabores integrados de .NET. Potencialmente, el .NET Gadgeteer

+3

No hay problemas con el boxeo. No reinventes la rueda. 'List ' existe por una razón; usarlo! – SLaks

+0

Tenía una sensación Lista era la respuesta para cualquier cosa por encima de 500 objetos, pero tengo curiosidad después de leer esto (buscar 500) http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx – LamonteCristo

+0

¿Hay boxeo problemas con System.Array? – LamonteCristo

Respuesta

20

se debe utilizar un List<T>.

El uso de Array.Resize le obligará a expandir el conjunto por separado cada vez que agregue un elemento, haciendo que su código sea mucho más lento. (dado que las matrices no pueden tener capacidad adicional)

A List<T> está respaldado por una matriz, pero tiene capacidad adicional para colocar elementos.
Todo lo que necesita hacer para agregar un elemento es establecer un elemento en la matriz y aumentar su contador interno size.
Cuando la matriz se llene, la lista doblará su capacidad, permitiendo que los artículos futuros se agreguen sin esfuerzo de nuevo.

+0

Tengo curiosidad sobre qué es lo mejor para 300 objetos ya que MSDN dice que la lista se paga por sí misma en aproximadamente 500 objetos – LamonteCristo

+0

Voy a crear muchas matrices de 300 objetos, por lo que entender esta optimización puede ser beneficioso, y no solo académico – LamonteCristo

+0

Eso es en comparación con 'ArrayList', que debe evitarse a toda costa (ya que no es genérico y requiere moldes y boxeo). Además, los 500 artículos no necesitan estar en una lista. Si tiene dos listas, igual valdrá la pena. – SLaks

2

.NET Micro Framework no es compatible con los genéricos, por lo que utilizaré una matriz, copiando y destruyéndolo según sea necesario.

me podría comparar esa perfmance a la lista enlazada desenrollado se menciona en la biblioteca de herramientas eléctricas aquí: Any implementation of an Unrolled Linked List in C#?

0

.NET Micro Framework no (todavía) los genéricos de apoyo. Estás limitado con respecto a las colecciones dinámicas.

Una cosa a tener en cuenta al momento de retirar su enfoque es que el código administrado en el microcontrolador es muy, muy lento. Muchas operaciones en los objetos de .NET Micro Framework administrados solo están llamando al código nativo para hacer el trabajo. Esto es mucho más rápido.

Por ejemplo, comparar la copia de un elemento de la matriz por el elemento en un bucle for frente llamando Array.Copy() que esencialmente hace lo mismo pero en código nativo.

Siempre que sea posible, use estas extensiones nativas para obtener un mejor rendimiento. También considere echar un vistazo a MicroLinq project en CodePlex. Hay un subproyecto dedicado solo a colecciones mejoradas en NETMF (también disponible como NuGet package). El código está disponible gratuitamente y tiene licencia abierta para cualquier propósito. (Descripción completa: soy el desarrollador de ese proyecto.)

Si puede salirse con la asignación de una gran matriz y hacer un seguimiento de la posición máxima en la que se han guardado los datos reales, este sería el más rápido pero requiere más trabajo/pensamiento puesto en el diseño y le quita tiempo a la construcción de las cosas interesantes.

0

La lista solo será más rápida si cambia el tamaño de la matriz con frecuencia, por ejemplo, cada vez que agrega un elemento. Sin embargo, si cambia el tamaño de cada pocos fotogramas, la lista y las matrices integradas deberían ser equivalentes, quizás las matrices sean aún más rápidas.

0

He visto la implementación de la lista después de la descompilación y encontré que usa Array.Resize() para la matriz interna. Pero administra el contador de elementos y utiliza la capacidad de la matriz como capacidad y cambia el tamaño de la matriz con un poco de espacio adicional cuando llamas a Add(). Entonces, supongo que puede desarrollar una estrategia de asignación más óptima que List para su caso. Pero tendrá que administrar el contador de elementos manualmente. También podrá deshacerse de los indexadores cuando acceda a los elementos de la matriz, ya que los indexadores dentro de List son solo métodos que solicitan elementos internos de la matriz. Creo que vale la pena reemplazar Lista por matriz con cambio de tamaño manual si solo es un cuello de botella.

Cuestiones relacionadas