2009-05-21 27 views
6

Ho ereditato un progetto in cui il modello dati dell'applicazione è un documento XML. Gli sviluppatori prima di me avevano creato un modello a oggetti basato sullo schema di questo xml e quindi codificato sul modello a oggetti.La serializzazione XML è lenta

Dopo diversi anni di manutenzione, questa applicazione ha gradualmente iniziato a mostrare la sua età. Il team leader ha affermato che il motivo principale alla base di questo è dovuto alla "lentezza" della serializzazione xml. Sono tentato di chiamare BS su questo, ma molti dei file xml con cui abbiamo a che fare sono di dimensioni superiori a 2 MB, e tenendo a mente le basi di ciò che accade dietro le quinte con gli oggetti contrassegnati [Serializable], 2MB è molto da riflettere su quindi potrebbe esserci un po 'di verità nella teoria della lentezza.

Nella tua esperienza, la serializzazione è davvero così 'lenta'/cattiva da optare per un modello XML -> XPath invece di un modello XML -> POCO?

BTW questo è un progetto .NET 2.0, ei nostri clienti potrebbero aggiornarsi a .NET 3.5 un po 'alla fine del prossimo anno.

risposta

6

In generale, no, non penso che il rallentamento sia dovuto alla serializzazione XML; 2 MB non è così grande e non dovrebbe causare alcun rallentamento importante.

Ciò di cui sarei più preoccupato è il capo del team che ti dice a cosa è dovuto il rallentamento senza fornirti alcuna informazione di profilazione specifica. MOSTRA che è così. Le opinioni sull'ottimizzazione sono spesso sbagliate; la profilazione esiste allo scopo di individuare con precisione dove si sta verificando un rallentamento in un'app. Suggerirei di strumentare e di profilare l'app, e di trovare dov'è il rallentamento; Scommetto che non è nella serializzazione XML.

6

La serializzazione Xml non utilizza l'attributo Serializable. Il serializzatore xml genera in realtà un assembly che associa l'xml all'oggetto, non usa il reflection. Questo è uno dei motivi per cui la serializzazione Xml funziona solo con i pubblici.

Una cosa che si può provare è misurare usando lo DataContractSerializer che fa parte di WCF. Sarebbe interessante vedere la differenza.

Non ho mai incontrato personalmente un limite di prestazioni, ma non ho anche oggetti di grandi dimensioni come la descrizione.

Una cosa da tenere a mente è il costruttore che si utilizza per creare il XmlSerializer, alcuni di essi non memorizzano nella cache l'assembly generato e si tradurranno in una perdita di prestazioni e una perdita di memoria in quanto ogni chiamata genererà sempre più assiemi . In questo caso sono disponibili due opzioni:

1) Memorizza nell'istanza del serializzatore che hai creato. Credo che sia thread-safe ma vorrete ricontrollare MSDN.
2) Utilizzare un altro costruttore per creare XmlSerializer.

+0

+1 ottima risposta. Per inciso, ricordo di aver visto alcuni benchmark su DataContractSerializer che mostravano una media di circa il 10% più veloce di XmlSerializer. – womp

+0

-1 Poiché la serializzazione XML * sicuramente utilizza * Reflection; non c'è modo di ottenere dettagli del tipo * a meno che * non abbia usato Reflection. Ora, questi dettagli non devono essere usati * ripetutamente * ma devono essere ottenuti in primo luogo. Inoltre, 'DataContractSerializer' è * non * parte di WCF; WCF lo sfrutta pesantemente, ma si trova all'esterno di WCF (nel proprio spazio dei nomi e nel proprio assembly). – casperOne

+0

@casperOne Il serializzatore XML utilizza la riflessione come si è detto la prima volta assumendo che si stiano chiamando i costruttori corretti in cui verrà memorizzato nella cache l'assembly risultante. Credo che si possa anche generare questo al momento della compilazione – JoshBerke

1

Eseguire un profiler e vedere dove viene speso la maggior parte del tempo della CPU. Sia che si tratti della serializzazione XML o da qualche altra parte, saprai dove concentrare i tuoi sforzi. Inoltre, per la cronaca, ho visto la serializzazione XML sorprendentemente lenta in passato nel mondo Java quando si lavora con Spring RPC. Quindi, è certamente possibile che il tuo capo abbia ragione, ma piuttosto che indovinare, dovresti controllare.

1

Come non è stato ancora menzionato qui, ho pensato di far notare che esiste un'opzione in VS per generare assembly di serializzazione XML in fase di compilazione.

http://msdn.microsoft.com/en-us/library/kb4wyys2(v=VS.100).aspx

Si potrebbe anche usare sgen.exe manualmente per fare la generazione se si vuole un controllo più capillare.

Questo riduce il tempo necessario per serializzare un tipo poiché, come dice JoshBerke in precedenza, XmlSerialiser genera un nuovo assembly ogni volta che è necessario eseguire la serializzazione o la deserializzazione, operazione che può richiedere del tempo per tipi complessi. La pre-generazione degli assiemi di serializzazione può pertanto comportare significativi miglioramenti delle prestazioni.

Problemi correlati