2012-02-29 22 views
6

Uso un XmlSerializer para serializar/deserializar algunos objetos. El problema es el rendimiento. Al crear perfiles, utilizando el XmlSerializer, nuestra aplicación tardará 2 segundos más en comenzar. Almacenamos en caché nuestro XmlSerializer y lo reutilizamos. No podemos usar sgen.exe porque estamos creando el XmlSerializer con XmlAttributeOverrides.Mejore el rendimiento de XmlSerializer

Intento utilizar una alternativa de serialización como Json.Net y, al principio, funciona muy bien. El problema es que tenemos que ser compatibles con versiones anteriores, por lo que todos los xml ya generados deben analizarse correctamente. Además, la salida de serialización del objeto debe ser Xml.

En resumen:

  1. recibo de datos XML serializado por un XmlSerializer.
  2. Necesito deserializar los datos Xml y convertirlos en un objeto.
  3. necesito para serializar objetos a XML (lo ideal es un formato XML como el que un XmlSerializer habría hecho)
+0

Sus datos XML contienen la etiqueta de apertura '' y la etiqueta de cierre ''. Supongo que es un error de tipeo. Además, en su pregunta usted define el formato de los datos de entrada, pero no es claro define el formato de la salida JSON. Exactamente como puede representar la misma información en diferentes formatos XML, puede producir diferentes datos JSON con el conjunto de información equivalente, pero en diferentes formatos. Creo que deberías definir más claro el formato de los datos de salida. – Oleg

+0

Sería bueno si también borra la restricción "No puedo usar un XmlSerializer". Si la razón es solo el rendimiento, existen muchas maneras de mejorar el rendimiento, utilizando sgen.exe o implementando la interfaz 'ISerializable'. Lo que no está claro en la pregunta: por qué tiene un formato de entrada tan extraño si los datos. ¿Tienes un archivo XML largo o tienes muchos de esos archivos? Normalmente uno tiene la información original en la base de datos. Entonces, ¿por qué necesita una entrada XML tan extraña en lugar de acceder a los datos * originales *? – Oleg

+0

Actualizo mi pregunta para representar más por el problema – Melursus

Respuesta

9

En última instancia, depende de la complejidad de su modelo. XmlSerializer tiene que pensar mucho, y el hecho de que me lleve tanto tiempo me lleva a sospechar que su modelo es bastante complejo. Para un modelo simple, podría ser posible implementar manualmente la deserialización usando LINQ-to-XML (bastante fácil), o incluso XmlReader (si se siente muy valiente, no es fácil obtener el 100% de precisión) .

Sin embargo, si el modelo es complejo, este es un problema y francamente sería muy arriesgado en términos de introducir errores sutiles.

Otra opción es DataContractSerializer que maneja xml, pero no tan bien como XmlSerializer, y ciertamente no con tanto control sobre el diseño. Sospecho fuertemente que DataContractSerializer no lo ayudaría.

No hay reemplazo directo para XmlSerializer que yo sepa, y si sgen.exe no es una opción que te creo, básicamente, tienen opciones:

  • vivir con ella
  • XmlSerializer de reescritura de ti mismo, de alguna manera sea mejor que ellos
  • usar algo como LINQ para XML y aceptar el esfuerzo que supone

a largo plazo, diría "formatos de cambio", y utilizar XML para importación heredada solamente. Conozco algunos protocolos binarios muy rápidos que serían bastante fáciles de sustituir; p

+0

Excelente respuesta. Tuve que hacer algo similar en un proyecto en el que tuve que usar interfaces y no usar clases abstractas (ya que C# no tiene herencia múltiple). El uso del linq to xml y la reflexión fue el truco. Mi siguiente tarea es hacer Atributos en lugar de una lista de reglas en los parámetros (solo aprendí sobre eso). Debo decir que es muy divertido. – pqsk

1

tienes que deserializar su lista utilizando una serialización .net clásico

algo como el siguiente :

TextReader tr = new StreamReader("yourlist.xml"); 
XmlSerializer serializer = new XmlSerializer(typeof(List<YourObject>)); 
List<YourObject> myCutomList = (List<YourObject>)serializer.Deserialize(tr); 
tr.Close(); 

continuación, puede utilizar la Json.Serialization

JavaScriptSerializer json = new JavaScriptSerializer(); 
JsonResult output = json.Serialize(myCutomList); 
+0

No puedo usar .net XmlSerializer porque en nuestro proyecto tiene un bajo rendimiento. Es por eso que trato de usar el JsonSerializer pero necesito ser compatible con nuestro viejo formato, así que necesito manejar Xml serializado por XmlSerializer sin usar un XmlSerializer ... – Melursus

0

Si tiene xml almacenado en el formato que no puede usar, utilice xslt para transformarlo al formato que puede usar.

Si este xml se almacena en el formato XmlSerializer, digamos en archivos planos, o un db, puede ejecutar sus transformaciones una vez y no incurrir en la sobrecarga de XmlSerializer en su tiempo de ejecución habitual.

Como alternativa, puede hacerlo en tiempo de ejecución, pero dudo que sea más rápido que el método descrito por Massimiliano.

0

This respuesta tiene alguna buena información sobre por qué XmlSerializer se ejecuta lentamente con XmlAttributeOverrides.

¿Realmente necesita usar el XmlSerializer en su hilo principal al inicio?

Quizás lo ejecute en un hilo de fondo; Si solo algunas partes de los datos son obligatorios para el inicio, quizás pueda leerlos manualmente en versiones proxy/dispersas de las clases reales mientras se inicializa el XmlSerializer.

Si es una aplicación GUI que podría simplemente añadir una pantalla de bienvenida para ocultar el retraso (o un juego de Tetris !!)

Si todo lo demás falla no puedes convertir los archivos existentes a JSON con sólo correr la deserialización existente y una serialización JSON, o existe un requisito difícil para mantenerlos XML?

0

Puede utilizar el enhebrado o las tareas para que la aplicación se inicie más rápido y no espere a que la aplicación funcione o la deserialización.

2

El problema es que está solicitando tipos que no están cubiertos por sgen, lo que da como resultado la generación de nuevos conjuntos durante el inicio.

Puede tratar de poner sus manos en los archivos temporales generados por Xmlserializer para sus tipos específicos y usar este código para su propio ensamblaje xmlserializer pregnerated. He usado este approach to find out why csc.exe se ejecutó lo que retrasó el inicio de mi aplicación.

Además de esto, puede ser útil renombrar algunos tipos como en el artículo para llegar a los mismos nombres que sgen está creando para poder usar sgen. Por lo general, las matrices de tipo no son pretratadas por sgen, lo que a veces es una lástima. Pero si nombra su clase ArrayOf HereGoesYourTypeName, entonces podrá usar los ensamblajes pregenerados.

Cuestiones relacionadas