2010-08-22 19 views
9

Ich lese sehr oft, dass der BinaryFormatter eine bessere Leistung als XmlSerializer hat. Aus Neugier habe ich eine Test-App geschrieben.Leistung: BinaryFormatter vs XmlSerializer

ein wtf Moment ... Warum ist Xml so viel schneller als Bin (vor allem die Deserialisierung)?

using System; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 
using System.Xml.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.IO; 

namespace SerPlayground 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var items = new List<TestClass>(); 
      for (int i = 0; i < 1E6; i++) 
      { 
       items.Add(new TestClass() { Name = i.ToString(), Id = i }); 
      } 

      File.Delete("test.bin"); 
      using (var target = new FileStream("test.bin", FileMode.OpenOrCreate)) 
      { 
       System.Threading.Thread.Sleep(1000); 
       var bin = new BinaryFormatter(); 
       var start = DateTime.Now; 
       bin.Serialize(target, items); 
       Console.WriteLine("Bin: {0}", (DateTime.Now - start).TotalMilliseconds); 

       target.Position = 0; 
       System.Threading.Thread.Sleep(1000); 
       start = DateTime.Now; 
       bin.Deserialize(target); 
       Console.WriteLine("Bin-D: {0}", (DateTime.Now - start).TotalMilliseconds); 
      } 

      File.Delete("test.xml"); 
      using (var target = new FileStream("test.xml", FileMode.OpenOrCreate)) 
      { 
       System.Threading.Thread.Sleep(1000); 
       var xml = new XmlSerializer(typeof(List<TestClass>)); 
       var start = DateTime.Now; 
       xml.Serialize(target, items); 
       Console.WriteLine("Xml: {0}", (DateTime.Now - start).TotalMilliseconds); 

       target.Position = 0; 
       System.Threading.Thread.Sleep(1000); 
       start = DateTime.Now; 
       xml.Deserialize(target); 
       Console.WriteLine("Xml-D: {0}", (DateTime.Now - start).TotalMilliseconds); 
      } 

      Console.ReadKey(); 
     } 
    } 

    [Serializable] 
    public class TestClass 
    { 
     public string Name { get; set; } 
     public int Id { get; set; } 
    } 
} 

meine Ergebnisse:

Bin: 13472.7706 
Bin-D: 121131.9284 
Xml: 8917.51 
Xml-D: 12841.7345 
+1

Deserialisierung weit langsamer als Serialisierung ist. Können Sie Ihre Probe ändern, um beides zu tun? Das wird ein viel interessanterer Vergleich sein. –

+0

Hallo, Ich würde in Betracht ziehen, einige Ihrer Tests mehrere (100+?) Mal - entweder mit dem Start (Erstellen der Formatierer/Serialisierer) in der Schleife enthalten oder ohne. Timing das Ergebnis von vielen weiteren Läufen können Sie ein genaueres Bild der Leistung geben. Erwägen Sie auch, die StopWatch-Klasse zu verwenden, um das Timing zu tun, da ich glaube, dass es den Hochleistungszeitgeber wo möglich verwendet. Wenn Sie immer noch eine schnellere XML-Serialisierung erhalten, wäre es gut zu wissen, warum auch! – Jennifer

+0

Ich habe immer verstanden, dass Binär ist "schneller" in Bezug auf die Netzwerkübertragung, da es weniger Bytes enthalten wird. Ich würde erwarten, dass es eine ziemlich starke Nutzlast braucht, um den Unterschied zu erkennen. – kbrimington

Antwort

7

Weil Sie ein Objekt Serialisierung, die keine Eigenschaften hat.

Wenn Sie etwas anderes serialisieren, das tatsächlich einige Daten enthält, wie z. B. eine Zeichenfolge, ist der binäre Serialisierer viel schneller als der XML-Serialisierer.

habe ich diese Änderung an Ihrem Code:

items.Add("asfd"); 

und ich dieses Ergebnis:

Xml: 1219.0541 
Bin: 165.0002 

Ein Teil der Differenz ist natürlich, dass die XML-Datei etwa zehnmal größer ist als die Binärdatei.

+1

Bemerkenswert ist, dass das Ganze fast doppelt so schnell läuft, wenn Sie die Position der XML- und BIN-Blöcke vertauschen (obwohl der Zeitanteil zwischen den Blöcken ungefähr gleich bleibt). Ich glaube also, dass der gesamte Benchmark verdächtig ist, vielleicht aufgrund der Speicherbereinigung oder eines anderen Faktors. –

+2

asfd - Amerikanische Gesellschaft der Möbeldesigner? –

+0

& Rober Harvey: Ich habe eine komplexere Klasse hinzugefügt ... swapping von XML und BIN macht jetzt keine Änderungen ... Ergebnis ist das gleiche XML ist schneller – Lukas

3

Das Beispiel ist ziemlich gut und die Frage ist interessant (ich mit Robert einverstanden, dass Sie die Main-Methode selbst mindestens einmal, bevor Sie Messungen tun als Initialisierung von variuos Sorten laufen sollten nicht Teil der Prüfung berücksichtigt werden.)

Ein wichtiger Unterschied zwischen XmlSerializer und BinaryFormatter (abgesehen von der offensichtlichen) ist, dass XmlSerializer nicht versucht, Verweise zu verfolgen. Wenn Ihr Objektdiagramm mehrere Verweise auf dasselbe Objekt enthält, erhalten Sie mehrere Kopien im XML-Code, die bei der Deserialisierung nicht ordnungsgemäß aufgelöst werden (zurück in ein einzelnes Objekt). Schlimmer, wenn Sie Zyklen haben, kann das Objekt überhaupt nicht serialisiert werden. Vergleichen Sie dies mit BinaryFormatter, das Verweise nachverfolgt und das Objektdiagramm zuverlässig rekonstruiert, egal wie viele und welche Objektverweise Sie haben. Vielleicht ist der Aufwand dieser Einrichtung für die schlechtere Leistung verantwortlich?

Der Hauptgrund für die Verwendung von BinaryFormatter über XmlSerializer ist die Größe der Ausgabe, nicht die Leistung der Serialisierung/Deserialisierung. (Der Kopftext der Konstruktion ist nicht so groß, es ist der Transport dieses xml Textes, der teuer ist.)