2009-05-21 5 views
6

Ich habe ein Projekt geerbt, wo das Datenmodell der Anwendung ein XML-Dokument ist. Die Entwickler vor mir hatten basierend auf diesem XML-Schema ein Objektmodell erstellt und dann gegen das Objektmodell codiert.XML-Serialisierung ist langsam

Nach mehreren Jahren der Wartung hat diese Anwendung allmählich begonnen, ihr Alter zu zeigen. Der Teamleiter sagte, dass der Hauptgrund dafür in der "Langsamkeit" der XML-Serialisierung liegt. Ich bin versucht, BS dabei zu nennen, aber viele der XML-Dateien, mit denen wir arbeiten, sind über 2MB groß, und unter Berücksichtigung der Grundlagen dessen, was hinter den Kulissen mit [Serializable] gekennzeichneten Objekten passiert, ist 2MB eine Menge nachzudenken also könnte die Langsamkeitstheorie etwas Wahrheit enthalten.

Ist Ihre Serialisierung wirklich so "langsam"/schlecht, dass Sie sich für ein XML -> XPath-Modell anstelle eines XML -> POCO-Modells entscheiden?

BTW ist dies ein .NET 2.0-Projekt, und unsere Kunden möglicherweise Upgrade auf .NET 3.5 irgendwann Ende nächsten Jahres.

Antwort

6

Im Allgemeinen, nein, ich glaube nicht, dass die Verlangsamung auf die XML-Serialisierung zurückzuführen ist; 2MB ist nicht so groß und sollte keine große Verlangsamung verursachen.

Worüber ich mehr besorgt wäre, ist der Teamleiter, der Ihnen sagt, worum es bei der Verlangsamung geht, ohne Ihnen spezifische Profilinformationen zu geben, die Ihnen zeigen, dass dies der Fall ist. Meinungen zur Optimierung sind häufig falsch; Profiling existiert, um genau herauszufinden, wo in einer App eine Verlangsamung stattfindet. Ich würde empfehlen, die App zu instrumentieren und zu profilieren und herauszufinden, wo die Verlangsamung ist. Ich würde wetten, dass es nicht in der XML-Serialisierung ist.

6

Xml Serialisierung verwendet das Serializable-Attribut nicht. Der XML-Serializer generiert tatsächlich eine Assembly, die das XML dem Objekt zuordnet, es verwendet keine Reflektion. Dies ist einer der Gründe, warum Xml Serialization nur mit publics funktioniert.

Eine Sache, die Sie versuchen könnten, ist die Messung mit der DataContractSerializer, die Teil von WCF ist. Es wäre interessant, den Unterschied zu sehen.

Ich bin persönlich nie auf eine Leistungseinschränkung gestoßen, aber ich habe auch keine großen Objekte wie Ihre Beschreibung.

Eine Sache, auf die Sie achten sollten, ist der Konstruktor, den Sie verwenden, um die XmlSerializer zu erstellen, einige von ihnen nicht die generierte Assembly zwischenspeichern und wird zu einem Leistungsverlust und einem Speicherverlust führen, da jeder Aufruf mehr und mehr Baugruppen generiert . Wenn dies der Fall ist, haben Sie zwei Optionen:

1) Zwischenspeichern Sie die von Ihnen erstellte Serializer-Instanz. Ich glaube, dass es threadsicher ist, aber Sie sollten MSDN überprüfen.
2) Verwenden Sie einen anderen Konstruktor, um den XmlSerializer zu erstellen.

+0

+1 große Antwort. Nebenbei erinnere ich mich an einige Benchmarks auf DataContractSerializer, die im Durchschnitt etwa 10% schneller waren als der XmlSerializer. – womp

+0

-1 Weil XML-Serialisierung * definitiv * Reflection verwendet; Es gibt keine Möglichkeit, Typdetails * zu erhalten, es sei denn * es wurde Reflection verwendet. Nun müssen diese Details * nicht wiederholt verwendet werden, aber sie müssen erst erhalten werden. Außerdem ist der 'DataContractSerializer' nicht Teil von WCF; WCF nutzt es stark, aber es befindet sich außerhalb von WCF (in seinem eigenen Namespace und seiner eigenen Assembly). – casperOne

+0

@casperOne Der XML-Serializer verwendet Reflektion, wie Sie beim ersten Mal gesagt haben, vorausgesetzt, Sie rufen die richtigen Konstruktoren auf, die die resultierende Assembly zwischenspeichern. Ich glaube, du kannst das auch zur Kompilierzeit generieren – JoshBerke

1

Führen Sie einen Profiler aus und sehen Sie, wo die meiste CPU-Zeit verbraucht wird. Ob es sich nun um die XML-Serialisierung oder anderswo handelt, Sie werden wissen, wo Sie sich konzentrieren sollten. Außerdem habe ich gesehen, dass die XML-Serialisierung in der Vergangenheit in der Java-Welt überraschend langsam war, als sie mit Spring RPC arbeitete. Es ist also möglich, dass dein Chef recht hat, aber anstatt zu raten, solltest du nachschauen.

1

Da es hier noch nicht erwähnt wurde, dachte ich, dass es eine Option in VS gibt, XML-Serialisierungsassemblys zur Build-Zeit zu generieren.

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

Sie könnten auch sgen.exe verwenden manuell die Generation zu tun, wenn Sie mehr feinkörnige Kontrolle wollen.

Dies reduziert die Zeit, die benötigt wird, um einen Typ zu serialisieren, da XmlSerialiser, wie JoshBerke oben sagt, eine neue Assembly generiert, wann immer er serialisieren oder deserialisieren muss, was bei komplexen Typen Zeit braucht. Das Vorgenerieren Ihrer Serialisierungsassemblys kann daher zu erheblichen Leistungsverbesserungen führen.