Tengo dos sugerencias para tratar:
En primer lugar, ¿qué pasa con el uso del reflector o ILSpy para mirar dentro Genérico List<T>
? Supongo que la implementación no está en el CF o podría usarlo. Genérico List<T>
está respaldado por una matriz y utiliza un algoritmo de duplicación que comienza en una matriz de longitud 4, cada llamada a .Agregar sobre la Capacidad hace que se duplique y realice una Array.Copy en la nueva matriz. No cambia de tamaño a menos que establezca explícitamente Capacidad en cero, así que tenga cuidado desde el punto de vista de la memoria. Las adiciones son una cosa, pero cada Eliminar hará que la matriz se copie y se mueva hacia la izquierda después del índice que se eliminó.
La segunda sugerencia es esta: ¿qué tal crear una clase personalizada que envuelve una matriz entera para manejar esto que usa un algoritmo doble similar (o cuadruplicado) a List<T>
genérico (para manejar el cambio de tamaño) pero comienza en dicho tamaño 256. Puede agregar ID de objeto entero a este fuera de orden tan rápido como quiera y no se duplicará con demasiada frecuencia. También puede simular una eliminación al designar (int) -1 o uint.MaxValue como un "índice nulo", lo que significa que no hay Array.Copy on remove. Luego, aplique algún tipo de clasificación rápida por cuadro para ordenar el conjunto de índices de objetos antes de dibujar. Si ordena de forma ascendente todos sus -1s aparecerán al inicio (o uint.MaxValues al final) y pueden ser ignorados. Puede "recopilar" periódicamente el conjunto de índices cambiando el tamaño y eliminando el anterior -1
en un hilo separado (cuidado - use el bloqueo;)
¿Qué opina? Sólo de pensar que va a compensar algunos de computación una vez por cuadro para la clasificación rápida (no es caro en Xbox vs asignación de memoria/recogida en cada Retire y algunos agrega (caro)
ACTUALIZACIÓN -. BlockArray - Lista < T [] donde > T es una matriz de tamaño fijo
He estado experimentando recientemente con la estructura de datos más eficiente para listas de tamaño dinámico y descubrí por experimentación que los bloques de matriz - una clase que está respaldada por una Lista de T [ ], donde cada T [] era una matriz de bloque de tamaño fijo, por ejemplo 512, 4096, 8192 como varias ventajas sobre una lista simple <T>.
he encontrado que una implementación de add() (donde el tamaño es desconocido) en una lista < T [] > enormemente superó Añadir() para la Lista <T>, especialmente cuando el tamaño total se hizo más grande. Esto se debe al < de la lista > del algoritmo de duplicación que solicita una nueva matriz 2x del tamaño de la antigua, y la matriz anterior de memcpy siempre que se excede el tamaño.
La velocidad de iteración es similar. La preasignación (capacidad predefinida) fue mucho más lenta que la Lista <T> para tamaños de bloques pequeños (512), pero solo un poco más lenta para tamaños de bloques grandes (8192). Las eliminaciones son problemáticas, ya que requieren copiar/dejar desplazando muchos bloques.
Lo interesante es en una lista < T [] > (lista de bloqueos), puede almacenar en caché o agrupar los bloques. Si es lo suficientemente pequeño, los bloques de T [] caben en el pequeño montón de objetos (favoreciendo la compactación, una asignación más rápida), pueden caber en la memoria caché L2 y se pueden preasignar y agrupar varios bloques
¿Qué tal un 'HashSet'? No tengo idea si eso está en el marco compacto. Pero debe iterar decentemente rápido y puede agregar/eliminar elementos rápidamente. Como está respaldado por una matriz, tiene muy pocas asignaciones. "pero debe ser el mismo con los mismos valores" podría ser un poco problemático, ya que no creo que 'HashSet ' lo garantice, incluso si es probable que sea así en la práctica. –
CodesInChaos
No está en el CF, que es mi razón principal para preguntar. Comprobando los iconos del constructor en el MSDN es como suelo decir si está allí o no (compare los iconos del constructor 'HashSet' 'List ' s (que es compatible). –
'HashSet' no parece ser aparte del marco compacto. –
SomeWritesReserved