2009-07-07 11 views
8

Estoy trabajando en una aplicación de marco compacto y necesito aumentar el rendimiento. La aplicación actualmente funciona sin conexión serializando objetos a XML y almacenándolos en una base de datos. Usando una herramienta de creación de perfiles pude ver que esto era bastante grande, ralentizando la aplicación. Pensé que si cambiaba a una serialización binaria, el rendimiento aumentaría, pero como esto no es compatible con el marco compacto, miré a protobuf-net. La serialización parece más rápida, pero la deserialización es mucho más lenta y la aplicación está haciendo más deserialización que la serialización.XML frente a rendimiento binario para serialización/deserialización

¿La serialización binaria debería ser más rápida y, de ser así, qué puedo hacer para acelerar el rendimiento? He aquí un fragmento de lo que estoy usando XML y binario:

serialización XML: serialización binaria

public string Serialize(T obj) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    MemoryStream stream = new MemoryStream(); 
    XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8); 
    serializer.Serialize(stream, obj); 
    stream = (MemoryStream)writer.BaseStream; 
    return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length)); 
} 
public T Deserialize(string xml) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));    
    return (T)serializer.Deserialize(stream); 
} 

Protobuf-net:

public byte[] Serialize(T obj) 
{ 
    byte[] raw; 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
    Serializer.Serialize(memoryStream, obj); 
    raw = memoryStream.ToArray(); 
    } 

    return raw;    
} 

public T Deserialize(byte[] serializedType) 
{ 
    T obj; 
    using (MemoryStream memoryStream = new MemoryStream(serializedType)) 
    { 
    obj = Serializer.Deserialize<T>(memoryStream); 
    } 
    return obj; 
} 
+0

Iba a sugerir usar el analizador de ANTS Red-Gate pero no funciona con el marco compacto (busque en google "red-gate hormigas perfilador compacto") – Kane

Respuesta

1

interesantes ... pensamientos:

  • qué versión de CF es esto; 2.0? 3.5? En particular, CF 3.5 tiene Delegate.CreateDelegate que permite protobuf-red para acceder a las propiedades mucho más rápido que en la lata en la FQ 2.0
  • estás anotando campos o propiedades ? Nuevamente, en CF las optimizaciones de reflexión son limitadas; se puede obtener un rendimiento mejor sería en la FQ 3.5 con propiedades, al igual que con un campo de la única opción que tengo disponible es FieldInfo.SetValue

Hay una serie de otras cosas que simplemente no existen en la FQ, por lo que tiene para hacer concesiones en algunos lugares. Para modelos demasiado complejos también hay un known issue with the generics limitations of CF. Se está realizando una reparación, pero se trata de un cambio grande, y está demorando "un momento".

Para información, algunas métricas en .NET (completo) comparando varios formatos (incluyendo XmlSerializer y protobuf-net) are here.

+0

Estoy usando CF2.0, y he atributos agregados a las propiedades de los objetos que necesito serializar. – Charlie

+0

¿Es posible probarlo en CF 3.5 (con el binario CF 3.5) solo para ver si eso lo soluciona? –

+0

Ok, acabo de ejecutar mi prueba en CF3.5 y veo un aumento significativo en el rendimiento de CF2; binary funciona mucho más rápido tanto para la serialización como para la deserialización. Desafortunadamente, estoy vinculado al CF2, así que podría tener que replantearme las cosas. – Charlie

0

¿Ha intentado crear clases personalizadas de serialización para sus clases? En lugar de usar XmlSerializer, que es un serializador de propósito general (crea un montón de clases en tiempo de ejecución). Hay una herramienta para hacer esto (sgen). Lo ejecuta durante su proceso de compilación y genera un ensamblaje personalizado que se puede usar en el ritmo de XmlSerializer.

Si tiene Visual Studio, la opción está disponible en la pestaña Generar de las propiedades de su proyecto.

0

¿El rendimiento se ve afectado al serializar los objetos o escribirlos en la base de datos? Dado que escribirlos probablemente está afectando a algún tipo de almacenamiento lento, me imagino que será un golpe de percusión mucho más grande que el paso de serialización.

Tenga en cuenta que las mediciones de perforación publicadas por Marc Gravell están probando el rendimiento en más de 1,000,000 de iteraciones.

¿En qué tipo de base de datos los está almacenando? ¿Los objetos están serializados en memoria o directamente en almacenamiento? ¿Cómo están siendo enviados al DB? ¿Qué tan grandes son los objetos? Cuando uno se actualiza, ¿envía todos los objetos a la base de datos, o solo el que ha cambiado? ¿Estás almacenando en memoria caché algo en la memoria, o volviendo a leer desde el almacenamiento cada vez?

+0

Los objetos se almacenan en una base de datos SQLCe, pero puedo ver claramente que la serialización y deserialización es el golpe de rendimiento, no la interacción de la base de datos. Las cosas también se almacenan en la memoria, pero necesita almacenar cosas en una base de datos para que pueda ser recuperada entre las sesiones de la aplicación. – Charlie

5

Me voy a corregir en esto, Marc Gravall señaló que la primera iteración tiene una sobrecarga de creación del modelo, así que hice algunas pruebas tomando el promedio de 1000 iteraciones de serialización y deserialización para XML y binario . Primero probé mis pruebas con la v2 de Compact Framework DLL y luego con la v3.5 DLL. Esto es lo que obtuve, el tiempo está en ms:

.NET 2.0 
================================ XML ====== Binary === 
Serialization 1st Iteration  3236  5508 
Deserialization 1st Iteration 1501  318 
Serialization Average   9.826  5.525 
Deserialization Average   5.525  0.771 

.NET 3.5 
================================ XML ====== Binary === 
Serialization 1st Iteration  3307  5598 
Deserialization 1st Iteration 1386  200 
Serialization Average   10.923  5.605 
Deserialization Average   5.605  0.279 
0

XML a menudo es lento de procesar y ocupa mucho espacio. Ha habido una serie de intentos diferentes para abordar esto, y el más popular de hoy parece ser simplemente colocar el lote en un archivo gzip, como con el Open Packaging Convention.

El W3C ha demostrado que el enfoque gzip es menos que óptimo, y ellos y varios other groups han estado trabajando en una mejor serialización binaria adecuada para el procesamiento rápido y la compresión, para la transmisión.

3

El gasto principal en su método es la generación real de la clase XmlSerializer. Crear el serializador es un proceso lento que solo debe hacer una vez para cada tipo de objeto. Intente almacenar en caché los serializadores y vea si eso mejora el rendimiento.

Siguiendo este consejo, vi una gran mejora de rendimiento en mi aplicación que me permitió continuar con el uso de la serialización XML.

Espero que esto ayude.

Cuestiones relacionadas