XML 序列化程式產生器工具

.NET程式在做XML序列化時,在效能上表現並不佳,因此提供了XML 序列化程式產生器工具來改善這個問題。使用XML 序列化程式產生器工具,可為指定組件中的型別建立 XML 序列化 (Serialization) 組件,以改善 XmlSerializer 在序列化或還原序列化指定型別物件時的啟動效能。

如果未使用 XML 序列化程式產生器,為指定組件中的型別建立XML 序列化組件。則每當應用程式執行時,XmlSerializer 便會為每個型別產生序列化程式碼和序列化組件,造成XML序列化緩慢。

何謂XML序列化組件呢?換句話說就是使用XML 序列化程式產生器所產生出來的檔案,也就是檔案命名後半部為XmlSerializers.dll的檔案,像是Data.XmlSerializers.dll。

這邊我們可以寫個簡單的程式來觀察這個現象,程式碼如下:

Imports System.Xml.Serialization
Imports System.IO

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim count As Integer = 1
        Dim perosn As New Person
        Dim xs As New XmlSerializer(GetType(Person))
        Dim sw As Stopwatch = Stopwatch.StartNew
        Using ms As New MemoryStream
            For i As Integer = 0 To count - 1
                ms.Seek(0, SeekOrigin.Begin)
                xs.Serialize(ms, perosn)
            Next
        End Using
        MsgBox("ElapsedMilliseconds: " & sw.ElapsedMilliseconds)
    End Sub
End Class

Public Class Person
    Private _name As String
    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Private _year As Integer
    Public Property Year() As Integer
        Get
            Return _year
        End Get
        Set(ByVal value As Integer)
            _year = value
        End Set
    End Property
End Class

運行後用ProcessMonitor去觀察,可發現當第一次執行到建立XmlSerializer物件的程式碼時,背後就在偷偷的找尋並試圖建立XML序列化組件。

Speed Up XML Serialization with the XML Serializer Generator Tool

使用XML 序列化程式產生器工具

要熟悉如何使用XML 序列化程式產生器工具來加速XML序列化的動作,先來看一下Sgen.Exe的用法。

Usage: sgen.exe [[/assembly:] | []]

[/type:] [/reference:] [/compiler:] [/debug] [/keep] [/nologo]

[/silent] [/verbose]

Developer options:

**/assembly:   Assembly location or display name. Short form is '/a:'.**    /type:       Generate code for serialization/deserialization of a single

             type from the input assembly. Short form is '/t:'.

/reference:  Reference metadata from the specified assembly files.

             Short form is '/r:'.

/compiler:   Visual C# compiler options to use while compiling generated

             code. Short form is '/c'.

             For complete list of available options see c# compiler help.

/proxytypes  Generate serialization code only for proxy classes and web

             method parameters. Short form is '/p'.

/debug       Generate image which can be used under a debugger.

             Short form is '/d'.

/keep        Keep source code and compiler temp files. Short form is '/k'.

**/force       Forces overwrite of a previously generated assembly.

             Short form is '/f'.**    /out:        Output directory name (default: target assembly location).

             Short form is '/o:'.

/parsableerrors

             Print errors in a format similar to those reported by

             compilers.

Miscellaneous options:

/? or /help  Show this message

/nologo      Prevents displaying of logo. Short form is '/n'.

/silent      Prevents displaying of success messages. Short form is '/s'.

**/verbose     Displays verbose output for debugging. Short form is '/v'.**                 List types from the target assembly that cannot be serialized

             with XmlSerializer.

最簡單的用法就是直接在命令後面接上組件名稱,像是:

Sgen XXX.dll

若產生的檔案可能已經存在,可加上/f參數強迫覆蓋。而若無法正確的產生XML序列化組件,可加上/v參數顯示造成無法產生的錯誤訊息。

使用上可在[專案]→[屬性]→[編譯]→[建置事件]內的建置後事件加上如下命令(命令路徑請依電腦實際狀況去做調整):

“%ProgramFiles%\Microsoft SDKs\Windows\v7.0A\bin\sgen.exe” /a:"$(TargetPath)" /force

Speed Up XML Serialization with the XML Serializer Generator Tool

如此建置後將在輸出目錄自動產生對應的XML序列化組件,將產生的XML序列化組件與自己撰寫的組件放在一起,序列化的速度就會提升了。

若仍嫌速度緩慢,也可以把產生的序列化組件加入參考,匯入Microsoft.Xml.Serialization.GeneratedAssembly命名空間,改用序列化組件內的Serializer取代XmlSerializer,像是:

Imports System.Xml.Serialization
Imports System.IO
Imports Microsoft.Xml.Serialization.GeneratedAssembly

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim count As Integer = 1000
        Dim perosn As New Person
        Dim xs As New PersonSerializer
        Dim sw As Stopwatch = Stopwatch.StartNew
        Using ms As New MemoryStream
            For i As Integer = 0 To count - 1
                ms.Seek(0, SeekOrigin.Begin)
                xs.Serialize(ms, perosn)
            Next
        End Using
        MsgBox("ElapsedMilliseconds: " & sw.ElapsedMilliseconds)
    End Sub
End Class

效能測試

這邊針對校能的改進作了一些測試,測試的CODE沿用上面的範例,實驗數據與結果如下:

次數無XML序列化組件有XML序列化組件使用XML序列化組件的Serialzer
100012510784
10000946884597
100000738259095924
100000062892 5915944779

Speed Up XML Serialization with the XML Serializer Generator Tool

  • XML 序列化程式產生器工具 (Sgen.exe)