2012-06-10 20 views
5

Tengo dos aplicaciones .NET ejecutándose de forma independiente (puede comenzar en cualquier orden, o puede ser una sola ejecución) que utiliza XML como almacén de datos. Entonces, ambas aplicaciones pueden leer y escribir en un archivo XML. Para mantener los datos actualizados, estoy cargando el archivo XML cada vez desde el disco antes de las operaciones de lectura y escritura. Y estoy usando la consulta XPath para consultar el nodo particular. Ahora se observa un problema de rendimiento en este método ya que hay solicitudes de lectura y escritura en XML cada segundo desde una aplicación (usa sondeo, y no se puede cambiar) No estoy seguro de qué está causando exactamente el rendimiento, pero creo su escritura de lectura continua.Cómo mejorar el rendimiento de lectura de lectura XML

He intentado usar archivos asignados de memoria de .NET 4.0, pero estoy restringido a usar .NET 3.5 y no a ninguna versión superior.

¿Alguien puede ayudarme con esto?

Nota: los nodos XML tienen algunos atributos comunes, un número diferente de atributos y un ID que utilizo para consultar XPath.

+3

¿Está seguro de que no puede implementar otra fuente de datos como Sql Server Compact? ¿Por qué no puedes cambiarlo? – rcdmk

+0

¿Consideró usar algo diferente de xml para ese uso? tal vez memcached (http://memcached.org/)? sql? si tiene que usar xml, intente utilizar XmlReader y XmlWriter – eyossi

+4

Si no puede cambiar la primera aplicación, sus opciones son muy limitadas. El mal diseño conduce a un mal rendimiento. – Filip

Respuesta

1

Intenta abrir el archivo exclusivamente. La otra aplicación puede fallar, pero si no falla, sabrá una cosa segura: no puede invocar mucha carga de E/S en un ciclo en el archivo compartido, porque todos sus intentos de acceso fallarán inmediatamente.

Esperemos que solo espere un segundo y vuelva a intentarlo, y eso debería funcionar bien para usted.

using (Stream iStream = File.Open("myfile.xml", 
      FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 
{ 
    ... 
} 
2

XML no está diseñado para consultas pesadas. Si necesita hacer esto, considere usar una base de datos. SQL Server Compact podría ser una buena alternativa. Si necesita seguir con XML y necesita trabajar con archivos de gran tamaño y necesita un rendimiento, considere usar XmlReader/XmlWriter que no están cargando todo el archivo en la memoria y son bastante rápidos.

+1

-1: si no pueden cambiar la aplicación, ¿cómo podría ayudar una base de datos? –

+0

De hecho, no noté esta restricción. XmlReader/XmlWriter como se menciona en mi respuesta es el camino a seguir en este caso. –

3

IF si está seguro de que el impacto en el rendimiento proviene de la E/S y no puede cambiar ambas aplicaciones, realmente hay un poco que puede hacer.

Primera solución con cero cambios en el código de la aplicación existente: utilice un RAM disk. Si están usando ese archivo como memoria compartida, puede hacerlo sin ningún otro cambio. Si los datos son persistentes, es posible que deba realizar una copia de fondo en otro medio después de cada escritura. El rendimiento no será tan bueno como una verdadera memoria compartida, pero al menos no tendrá que esperar operaciones lentas de E/S.

Segunda solución con cambios solo en la aplicación que debe leer datos: a menudo el análisis de un archivo XML es bastante lento (especialmente si está usando XmlDocument y el archivo no es muy pequeño). En este caso, usando XmlReader, tiene que hacer su código de lectura más complicado y olvidarse de las consultas XPath, pero su rendimiento será muchas veces mejor que XmlDocument y no se ralentizará aumentando el tamaño del archivo.

Actualizaciones pequeñas (o no tan pequeñas): si se puede cambiar el código de la segunda aplicación (supongo que el que leerá el archivo) puede mejorar un poco su rendimiento. Antes que nada, no lea el archivo cada vez. Compruebe su marca de tiempo, registre FileSystemWatcher para ese archivo o lo que sea, pero no lea/analice el archivo cada vez. Cuando lo haya hecho, puede ir un paso adelante: leer/analizar el archivo solo cuando cambie, prepare su XmlDocument en segundo plano (otra secuencia) y póngalo disponible para las solicitudes de sondeo.Si las solicitudes son espaciadas, incluso pueden ver un tiempo de respuesta muy rápido (pero el rendimiento del perfil de XmlDocument consulta XPath para su archivo típico).

EDIT: here puede encontrar un disco RAM provisto por Microsoft. Es bastante simple e ingenuo, pero por lo general usted/nosotros no necesitamos mucho más que eso. Además, es un ejemplo en el DDK, así que también obtendrás el código fuente (en este caso ... solo por diversión).

+0

+1 - El disco RAM es una de las pocas cosas que uno podría hacer con una aplicación mal diseñada, independientemente de lo mal diseñada que esté. –

+0

Por disco RAM, ¿te refieres a archivos compartidos/archivos en la memoria? – user1447725

+0

No, el disco RAM es un disco virtual que permanece en la memoria. La aplicación se verá como una unidad normal (se agregó un enlace). –

2

En lugar de leer el archivo XML muy a la vez, simplemente léalo la primera vez y también obtenga la última hora modificada para el archivo.

Cuando necesite saber si los datos están actualizados, simplemente verifique la hora de modificación del archivo y solo vuelva a leer el archivo si realmente ha cambiado.

+0

Si esa aplicación * realmente * escribe en el archivo cada segundo, esto no ayudará mucho. Pero esto se puede verificar fácilmente antes de escribir dicho código. –

2

No sondear el archivo. Léalo una vez y guárdelo en la memoria, luego use FileSystemWatcher para recargarlo solo cuando cambie.

O bien, lea la marca de tiempo de modificación y solo vuelva a cargar el archivo si la marca de tiempo cambió.


Además, al leer el archivo, asegúrese de bloquearlo de forma no exclusiva para que otros lectores no estén bloqueados.

Cuestiones relacionadas