Digamos que tengo muchos objetos que contienen cadenas de longitud no trivial (alrededor de ~ 3-4kb). Las cadenas son todas diferentes entre sí, pero al mismo tiempo contienen muchas partes/subsecuencias comunes. En promedio, quizás el 80-90% de una cuerda individual está contenida con las otras también. ¿Existe una manera fácil de explotar automáticamente esta gran redundancia para comprimir los datos?
Idealmente, la solución sería C++ y transparente para el usuario (es decir, puedo usarla como si estuviera accediendo a un estándar de lectura solo const std :: string pero en lugar de leer desde el almacenamiento comprimido).almacenamiento de cadena comprimida
Respuesta
Algorítmicamente, Lempel–Ziv–Welch con un diccionario para todos los objetos/cadenas podría ser un buen comienzo.
Si se crean dinámicamente muchas cadenas a lo largo del tiempo, este diccionario crecerá en grande. Así que, al final, puede ser una idea más simple y mejor que solo LZW comprima las cadenas por separado. –
Se crearán muy pocas cadenas una vez que se haya cargado el lote inicial, por lo que no esperaría un problema allí ... – BuschnicK
Si las partes comunes de las cadenas son comunes porque están compuestas de otras cadenas, entonces puede obtener algo de tracción usando la clase stlportrope
, que se ve por todo el mundo como std :: string, pero utiliza subcadena representación en árbol con copiar al escribir que los dos muy eficiente del espacio (subcadenas comunes son compartidos) y muy bueno en las inserciones y eliminaciones (log (n)) hace
al usar la cuerda:
- usted está haciendo un motor de plantilla. las instancias de documentos se crean a partir de una plantilla sustituyendo datos variables en la plantilla y luego se almacenan en caché para usos futuros. Las partes que son comunes a las plantillas y las instancias se almacenan solo una vez y se comparten entre instancias, insertos y eliminaciones son baratas.
Cuando no utilizar la cuerda:
- que está cargando muchos documentos desde fuera del dominio de la aplicación (desde el disco, o en una red) y su utilización sin modificaciones. la cuerda no comparte cuerdas si no se copian de una cuerda a otra. Si puede permitirse hacer el trabajo para encontrar las subcadenas comunes, la cuerda todavía se puede usar para mejorar sus representaciones finales.
Creo que tiene más que copiar en escritura. Creo que los datos se almacenan en un árbol de cadenas, no en una zona de memoria contigua. –
Es copy-on-write combinado con la capacidad de anteponer a cadenas con el mismo costo algorítmico que se agrega a ellos. –
Creo que encajo su segundo caso: mis cadenas no están controladas por mí y las obtengo de una base de datos. – BuschnicK
Puede usar huffman coding la implementación no es difícil, también hay algoritmos de zip en idiomas (como C# y java) y puede usarlos.
También Si está seguro de que el 80-90% se repite en todos, cree un diccionario de todas las palabras, luego, para cada cadena, la posición de la palabra del diccionario, significa que tiene una matriz de bits de gran tamaño (10000 ie) y marque posición relacionada bits[i]
a 1
si existe un words[i]
en la cadena actual. piense que cada longitud de palabra es de 5 caracteres, entonces la abreviatura toma alrededor de 1/5 de tamaño.
Como mencionó @Saeed, una codificación Huffman simple funcionará bien aquí.
No es necesario en el diccionario, si las palabras comunes se conocen a priori (ha mencionado que es un HTML). Simplemente precompute una tabla huffman utilizando datos estadísticos de muchos archivos HTML (tenga en cuenta que puede codificar una etiqueta entera con un solo símbolo, y puede tener tantos símbolos como desee).
- 1. Crear una carpeta comprimida (o comprimida)
- 2. Crear una carpeta comprimida (comprimida) usando Delphi
- 3. cómo detectar rápidamente si una cadena está comprimida zlib?
- 4. Representación gráfica comprimida?
- 5. Descomprimir la respuesta http comprimida gzip
- 6. Creando una carpeta comprimida o comprimida en Windows usando Powershell o la línea de comando
- 7. C++ cadena tipo de datos literal almacenamiento
- 8. Identificar imagen DICOM comprimida por etiqueta
- 9. aumentar los conceptos básicos de la matriz comprimida
- 10. Almacenamiento de datos binarios en cadena UTF-8
- 11. Makefile para combinar archivos js y crear una versión comprimida
- 12. Decodificar página web comprimida recuperada mediante cURL en PHP
- 13. Almacenamiento de Drupal SQL en Git
- 14. Escribir y leer Cadena en un almacenamiento interno en Android
- 15. almacenamiento local y almacenamiento de sesión
- 16. ASP.NET MVC - compresión + almacenamiento en caché
- 17. Almacenamiento de salida de shell
- 18. Uso de la salida comprimida de Sass dejando el encabezado de comentario del tema para Wordpress
- 19. Obtención de información de una sola desde una imagen comprimida del núcleo
- 20. Almacenamiento de tabla azul: ¿tamaño variable máximo?
- 21. ¿Se puede rotar una imagen JPEG comprimida sin pérdida de calidad?
- 22. Cadena de conexión del emulador de almacenamiento de Windows Azure para ASP.NET MVC?
- 23. Errores aislados de almacenamiento
- 24. Malentendido de almacenamiento aislado
- 25. Almacenamiento seguro de Eclipse
- 26. Almacenamiento de Greasemonkey
- 27. Almacenamiento de una matriz de valores clave en una cadena JSON compacta
- 28. comparación de direcciones y almacenamiento de cadenas
- 29. Almacenamiento de direcciones IPv6 en MySQL
- 30. Almacenamiento de matrices anidadas en una cookie
¿Cómo las cadenas llegan a tener subsecuencias comunes? ¿Esto se debe a ediciones repetidas o coincidencia de los datos? – SingleNegationElimination
Imagine HTML estático sin soporte para CSS. Tiene muchos html redundantes y solo unas pocas partes cambiantes que contienen la información real. – BuschnicK
1 GB de ram se mantendrá en el orden de 100.000 blobs sin comprimir con un tamaño de 3-4 KB. ¿Realmente lo necesitas para que quepa en menos? – SingleNegationElimination