Límites prácticos de tamaño de una tabla hash y un diccionario en c #

12

¿Cuáles son los límites prácticos para la cantidad de elementos que puede contener un diccionario o tabla hash de C # 4 y la cantidad total de bytes que estas estructuras pueden contener razonablemente? Trabajaré con un gran número de objetos y quiero saber cuándo estas estructuras comienzan a experimentar problemas.

Por contexto, usaré un sistema de 64 bits con toneladas de memoria. Además, necesitaré encontrar objetos usando alguna forma o 'clave'. Dadas las demandas de rendimiento, estos objetos deberán residir en la memoria y muchos durarán mucho.

Siéntase libre de sugerir otros enfoques / patrones, aunque necesito evitar el uso de bibliotecas de terceros o de código abierto. Por razones de especificación, necesito poder construir esto usando C # nativo ( o C ++ \ CLI ).

JoeGeeky
fuente
1
Debería tomar solo una hora o dos burlarse de eso y medir el rendimiento de agregar / quitar / buscar bajo diferentes usos / cargas. Creo que VS2010 incluso proporciona esqueleto de pruebas de rendimiento para usted. No importa lo que alguien diga aquí, el código que escribirá tendrá su nombre, directamente o en metadatos.
Trabajo

Respuestas:

8

Una cosa a señalar es que el Diccionario no va a contener el objeto en sí (que puede tener una gran huella de memoria) sino solo una referencia al objeto, por lo que si los objetos son complejos, esto no tiene impacto en el tamaño del Diccionario.

He reunido varios miles de elementos juntos en un Diccionario en memoria y el problema no es el tamaño del Diccionario sino el tamaño de los objetos en memoria. En estos casos, el Diccionario en sí era una pequeña porción de la memoria involucrada.

Una cosa a tener en cuenta en los casos de diccionarios grandes es configurar y administrar manualmente la capacidad del diccionario. En circunstancias normales, .Net administra esta multa (en la implementación actual, si se queda sin espacio, cambia el tamaño a un número primo que es al menos dos veces el tamaño actual del Diccionario). Sin embargo, si sabe que va a crear un diccionario grande o va a expandir el diccionario en lugar de .Net adivinar y cambiar el tamaño del diccionario para usted (lo cual es relativamente costoso), probablemente sea mejor que lo haga usted mismo (ciertamente con la inicial tamaño y, probablemente, la gestión de tamaños posteriores). Esto se puede hacer administrando la capacidad del Diccionario si tiene una idea heurística razonable de cuál debería ser la capacidad del Diccionario. Microsoft recomienda esto enMSDN en sus comentarios sobre el objeto Diccionario . Sin embargo, parece haber cierto debate sobre el valor real de este enfoque, aunque no estoy seguro de cuán rigurosa es esa prueba y si hay otras optimizaciones que la plataforma .Net implementa cuando un diccionario cambia el tamaño extremadamente rápido.

Esta es una pregunta útil de Stack Overflow sobre el objeto y el tamaño de la memoria.

AlexC
fuente
2

Los límites prácticos pueden ser relativos a la máquina en la que se ejecuta su software, así como a la cantidad de objetos que realmente planea contener dentro de estas estructuras de datos. Como mencionó Oded, int.MaxValue es un gran número, pero ¿2 mil millones de artículos equivalen a un límite práctico? Almacenar tantos elementos en la memoria probablemente no sea muy práctico.

Bernardo
fuente
0

Dado que la documentación no dice dónde se almacenan físicamente los datos y no especifica el límite, le sugiero que realice un experimento con el tamaño máximo esperado que tenga y tenga en cuenta la memoria del sistema antes y después de la asignación de almacenamiento.

Ninguna posibilidad
fuente
-1

Recientemente actualicé el proyecto github hash-table-shootout (aquí: https://github.com/jimbelton/hash-table-shootout ). El mapa desordenado gcc estándar tiene aproximadamente 1,8 GBytes de sobrecarga para almacenar 40 millones de objetos. Esto me parece bastante atroz, pero incluso el mejor en cuanto a memoria, el Google sparse_hash_map, toma 600 Mbytes, y usted paga una penalización de rendimiento por usarlo. Si desea velocidad, de los algoritmos incluidos, Glib GHashTable es el más rápido y tiene un buen rendimiento de memoria (alrededor de 1.3 Gbytes de sobrecarga). Los resultados de referencia se publican aquí: https://jimbelton.wordpress.com/2015/07/01/hash-table-shootout-on-github/

Jim Belton
fuente