Pregunta

Tengo algunos archivos de datos que se escriben como Tag = Value, donde la etiqueta es una cadena y el valor pueden ser numéricos, cadena, matriz, etc. Utilizo este formato porque es legible y se puede editar fácil. Ahora, cada clase que se instancia utilizando este formato tiene un método de carga y lee las etiquetas que necesita y usa los valores encontrados dentro de estas etiquetas. Quiero hacer que los datos binarios aumenten la velocidad de carga. Una forma sería tener un método de Tobinar (el nombre no importa) en cada clase que lea los datos antiguos y escribirlos en un archivo y el nuevo archivo se usa para instanciar el objeto. Esto se puede hacer fuera de línea, solo una vez/aplicación. ¿Tienes otras sugerencias para esto? Yo uso C ++ para esto.

Editar: Creo que la parte más cara ahora es analizar el archivo cuando lo leo por primera vez y después de eso para buscar la etiqueta que necesito, no leer el archivo desde el disco. Puedo usar el sistema de archivos personalizado para tener múltiples archivos pequeños en un archivo grande.

¿Fue útil?

Solución

Tengo una clase base de serialización para esto, con/desde funciones con un encabezado pequeño donde el manejo de la versión se puede incrustar. Creo que es un buen sistema para datos más simples que deben almacenarse localmente y en la mayoría de los casos es "solo leer".

Algo como esto:

class SeralizeMe
{
public:

 virtual bool To(Archive &file)=0;
 virtual bool From(Archive &file)=0;

 virtual bool NeedsSave(void)=0;

};

Sin embargo, no use este sistema si:

  • Necesita cambiar el formato a menudo.
  • Necesita seleccionar qué datos cargar y qué almacenar.
  • Use archivos grandes, que son particularmente sensibles a los cortes de energía mientras se guarda.

Si se aplica alguno de los anteriores, use una base de datos, Firebirdsql incrustado es un contendiente adecuado.

Otros consejos

No lo he usado antes, pero estoy seguro Módulo de serialización de Boost es un buen lugar para comenzar.

Si está utilizando un archivo, el uso de datos binarios probablemente no mejorará significativamente sus actuaciones, a menos que tenga una gran parte de datos para almacenar en el archivo (imágenes, videos ...).

Pero de todos modos, puedes usar un algoritmo de serialización binaria, como el de Impulsar.

Otro es ProtoBuf de Google. No es el más rápido, pero puede admitir tipos de datos en evolución y es muy eficiente en la red y admite otros idiomas.

Enlace aquí.

Si desea mejorar el rendimiento, tendrá que usar campos de longitud fija. Los campos de longitud variable de análisis o carga no proporcionan un aumento significativo en el rendimiento. La lectura por línea de texto implica escanear para el token de final de línea. Escanear desata el tiempo.

Antes de usar cualquiera de las siguientes sugerencias, perfile su código para establecer un tiempo o número de referencia para el rendimiento. Haga esto después de cada sugerencia, ya que le permitirá calcular el Delta de rendimiento de cada optimización. Mi predicción es que el delta se volverá más pequeño con cada optimización.

Sugiero primero convertir el archivo en registros de longitud fija, que todavía usa texto. Campos de almohadilla con espacios según sea necesario. Por lo tanto, conociendo el tamaño de un registro, puede bloquear la lectura en la memoria y tratar la memoria como una matriz. Esto debería proporcionar una mejora significativa.

En este punto, sus cuellos de botella siguen siendo una velocidad de E/S de archivos, en las que realmente no puede realizar mejoras significativas (porque el sistema operativo está controlado por el sistema operativo) y el texto de escaneo/conversión. Algunas optimizaciones adicionales son: convertir texto a números y finalmente convertir a binario. A toda costa, prefiera mantener el archivo de datos en forma legible humana.

Antes de hacer que el archivo de datos sea menos legible, intente dividir su aplicación en hilos. Un hilo maneja la GUI, otro la entrada y otro para el procesamiento. La idea es tener el procesador siempre Ejecutando parte de su código en lugar de esperar. En las plataformas modernas, la E/S de archivos se puede realizar mientras la CPU procesa su código.

Si no le importa la portabilidad, consulte si su plataforma tiene capacidad DMA (un componente de acceso a la memoria DMA o DMA permite transferencias de datos sin usar el procesador o minimizar el uso del procesador). Algo a tener en cuenta es que muchas plataformas comparten la dirección y el bus de datos entre procesador y DMA. Por lo tanto, el único componente se bloquea o se suspende mientras el otro usa la dirección y los buses de datos. Entonces puede ayudar o no. Depende de cómo esté conectado la plataforma.

Convierta el campo clave para usar números, también conocido como tokens. Dado que los tokens son numéricos, se pueden usar como índices en tablas de salto (también declaraciones de conmutación) o simplemente índices en matrices.

Como último recurso, convierta el archivo a binario. La versión binaria debe tener dos campos: clave como token y valor. Avance los datos en grandes fragmentos a la memoria.

Resumen

  1. Transportar grandes bloques de datos a la memoria.
  2. Perfil antes de hacer cambios para establecer una medición de rendimiento de referencia.
  3. Optimizar un paso a la vez, perfil después de cada optimización.
  4. Prefiere mantener el archivo de datos en forma legible humana.
  5. Minimizar los cambios en el archivo de datos.
  6. Convertir el archivo para usar campos de longitud fija.
  7. Intente usar hilos o multitarea para que la aplicación no esté esperando.
  8. Convertir el texto en tokens numéricos (reduce la legibilidad humana)
  9. Convierta los datos en binario como último recurso (muy difícil para los humanos de leer y depurar).

Tengo dos ideas para ti:

1) Si la lista de etiquetas es constante y conocida de antemano, puede convertir cada una en un byte (o palabra), seguido de la longitud del valor (en bytes), seguido de la cadena de ca sin procesar del valor carga útil.

Por ejemplo, dado lo siguiente:

Tag1 = "hello World!" // 12 bytes in length (achieved by "strlen(value) * sizeof(char)" )
Tag2 = "hello canada!"  // 13 bytes in length 

Podrías convertir esto en la transmisión de byte:

0x0001 0x000B // followed by 12 bytes representing the 'value' // 0x0002 0x000C // followed by 13 bytes representing 'value2'

Su programa solo necesitaría saber que el encabezado de la palabra "0x0001" representa TAG1, y el encabezado "0x0002" representa TAG2.

Puede abstraer aún más los nombres de las etiquetas si no los conoce por adelantado, siguiendo una estructura de valor de longitud similar.

2) ¿Quizás el bit lento es solo su implementación del análisis de texto? Considere usar una biblioteca de código abierto dedicada para lo que está tratando de hacer. Ejemplo: "Boost :: Property_tree"

Property Tree está diseñado específicamente para almacenar y recuperar pares de valores clave (diseñados para usar como archivo de configuración). Pero supongo que dependería de cuántos pares de estas estás tratando de almacenar para que esto sea económico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top