2012-07-30 11 views
6

Tengo una clase mutable que tiene un campo privado List<T> adentro. En el método Reset() de mi clase, ¿debo borrar la lista usando su método Clear() o simplemente asignarle a su campo una nueva lista? Tenga en cuenta que la lista no es pública y solo la usa la clase. Por lo tanto, asignar una nueva lista debe hacer que la anterior sea inalcanzable. Desde el método Clear()is an O(n) operation, me pregunto cuál es la desventaja de simplemente asignar una nueva lista sobre él.¿Borrando una colección privada o configurándola como nula?

Respuesta

5

El único inconveniente que se me ocurre es que si necesita usar la lista nuevamente, tendrá que asignarle un nuevo espacio.

Al anularlo, solo hará que la lista y su contenido (suponiendo que no haya otras referencias) sean elegibles para GC. Borrarlo eliminaría los elementos pero dejaría la memoria asignada.

Personalmente tiendo a anular la cosa, incluso si la necesito de nuevo, el tamaño habrá cambiado por completo.

Actualización: En relación con los comentarios siguientes, indica que estos objetos se administrarán en un grupo de objetos. Aconsejaría crear una pequeña aplicación de consola de perfiles para obtener la respuesta final. La discusión ahora se adentra en los detalles de su implementación y el uso previsto del conjunto de objetos, lo que podría cambiar fácilmente la respuesta.

En general, si tiene listas que no cambian mucho de longitud y siempre serán necesarias, utilizaría Clear para evitar asignar memoria nueva para las listas. Si la longitud de la lista es susceptible de muchos cambios, o el uso es a veces escaso, estaría a favor de anularlo para reclamar memoria y obtener algunos beneficios menores mediante la instanciación lenta de las listas.

+0

Entonces, si tengo una lista de bytes con 2k bytes, ¿cuál sería más rápido? ¿Yo, llamando a Clear o GC, haciendo una reasignación? Pregunto esto porque tengo alrededor de 1-2k de objetos con estas listas, así que quiero estar seguro de cuál sería mejor, en cuanto a rendimiento. –

+0

@ d4wn Personalmente, no me preocuparía el rendimiento hasta que pueda probar que es un problema. Depende de lo que quieras hacer con la lista. Si los elementos ya no son necesarios, pero es probable que necesite el tamaño de la lista o desee evitar la reasignación de memoria para el crecimiento de la lista, me gustaría 'Clear'. Si luego no te importa la lista o puede reducirse mucho, me gustaría 'list = null; list = new List () '. En cualquier situación, el GC recogerá x-muchos objetos por lo que no importa. Cualquier diferencia de rendimiento potencial será la diferencia entre la iteración de O (n) frente a la reasignación de crecimiento de la lista. –

+0

Entonces, una pregunta más: ¿Por qué querría "evitar la reasignación de memoria para el crecimiento de la lista"? Utilizo un grupo para estos objetos, que se reutilizarán una y otra vez mientras la aplicación se esté ejecutando. Hacer la reasignación cada vez parece caro, pero no sé mucho sobre GC y cuánto puede afectar este proceso el rendimiento. –

0

Entonces, ¿por qué null it? Esto va a hacer el truco para ti, dejando que la vieja estancia lista en el montón de recolección de basura, mientras que los métodos existentes que tienen acceso a la lista puede seguir funcionando en una nueva lista vacía:

this.FooList = new List<Foo>(); 
+1

Escribí "asignando a su campo una nueva lista" también. La razón por la que utilicé la palabra "anular" es porque hace que el campo sea inalcanzable y permite que el GC lo recopile. Pero tienes razón, debería editar la pregunta. De todos modos, la pregunta era cuál sería más rápido y qué ventajas/desventajas tienen sobre otro. –

+0

Anularlo o reasignarlo equivale a lo mismo a los ojos del GC. Si lo anula y lo vuelve a asignar más adelante, obtendrá un leve beneficio de creación de instancias perezosas. –

0

Después de la Reset llamada que dejaría el objeto en el mismo estado en que estaba después de haber llamado al constructor.

Si su constructor creó un nuevo List vacío, entonces hágalo. Si no, hágalo null.

+0

Eso es lo que trato de decidir. Establezca la lista una vez en el constructor y úsela una y otra vez borrándola, o créela perezosamente si es necesario y configúrelo como nulo (o para una nueva lista) en Restablecer. –

+0

@ d4wn En mi opinión, no creo que el rendimiento deba impulsar esta decisión. Creo que hacerlo 'nulo' y cargarlo perezosamente es lo más limpio, lo haría. – ForkandBeard

Cuestiones relacionadas