Hola tengo el siguiente problema: Estoy almacenando cuerdas y una lista correspondiente de valores enteros en una MultiValueMap<String, Integer>
Estoy almacenando cerca de 13 000 000 millones de cuerdas y una cadena puede tener hasta 500 o más valores. Por cada valor individual tendré acceso aleatorio en el Mapa. El peor de los casos son 13 000 000 * 500 llamadas al público. Ahora la velocidad del mapa es buena, pero la carga de la memoria es bastante alta. A MultiValueMap<String, Integer>
no es nada más que un HashMap/TreeMap<String, <ArrayList<Integer>>
. Tanto HashMap como TreeMap tienen mucha memoria por encima. No modificaré el mapa una vez que lo haya hecho, pero necesito que sea lo más rápido posible para el acceso aleatorio en un programa. (Lo estoy almacenando en el disco y lo estoy cargando al inicio, el archivo de mapa serializado ocupa unos 600 MB pero en la memoria es de aproximadamente 3 gb)memoria multivaluemap eficiente
Lo más eficiente en cuanto a la memoria sería almacenar el String en una matriz ordenada y tienen una matriz int bidimensional correspondiente para los valores. Entonces el acceso sería una búsqueda binaria en la matriz de cadenas y obtener los valores correspondientes.
Ahora tienen tres maneras de llegar:
Puedo usar un MultivalueMap ordenados (TreeMap) para la fase de creación para almacenar everything.After he terminado con la obtención de todos los valores, me sale la cadena array llamando al
map.keyset().toArray(new String[0]);
Crea una matriz int bidimensional y obtén todos los valores del mapa de valores múltiples. Pro: es fácil de implementar, todavía es rápido durante la creación. Con: Ocupa más memoria aún durante la copia de Map a Arrays.Uso Arrays o ArrayLists desde el principio y almaceno todo allí Pro: menos sobrecarga de memoria. Con: esto sería enormemente lento porque tendría que ordenar/copiar la matriz cada vez que agregue una nueva clave, también tendría que implementar mi propia clasificación (incluso más lenta) para mantener la matriz int correspondiente en el mismo orden como las cuerdas. Difícil de implementar
Utilizo Arrays y un MultivalueMap como búfer. Después de que el programa finalizó el 10% o el 20% de la fase de creación, agregaré los valores a las matrices y los mantendré en orden, luego comenzaré un nuevo mapa. Pro: Propaga lo suficientemente rápido y lo suficientemente eficiente desde el punto de vista de la memoria. Con: Difícil de implementar.
Ninguna de estas soluciones realmente me parece correcta. ¿Conoces otras soluciones a este problema, tal vez una implementación de mapas con memoria eficiente (MultiValue)?
Sé que podría estar utilizando una base de datos, así que no se moleste en publicarla como respuesta. Quiero saber cómo podría hacer esto sin usar una base de datos.
Pregunta rápida: 500 * 4 * 13,000,000 es 26,000,000,000 de bytes o +/- 24GB - ¿Está considerando almacenar estos datos de forma desordenada? –
Hi 500 es una estimación del peor caso, la mayoría de las cadenas tendrán solo 1 o 2 valores. En este momento estoy ejecutando el programa con -Xmx12g pero estoy almacenando valores adicionales en otro mapa. Como me entristece, Map ocupa alrededor de 3g en memoria y alrededor de 644mb en disco. – samy
Sry No obtuve el almacenamiento fuera de Heap, solo busqué en Google, parece interesante. – samy