9

BinaryFormatter のパフォーマンスが XmlSerializer よりも優れていることをよく読みます。好奇心から、テストアプリを書きました。

すごい瞬間...なぜXmlはBinよりもはるかに高速なのですか(特に逆シリアル化)?

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; }
    }
}

私の結果:

Bin: 13472.7706
Bin-D: 121131.9284
Xml: 8917.51
Xml-D: 12841.7345
4

3 に答える 3

7

プロパティを持たないオブジェクトをシリアル化するためです。

文字列など、実際にデータを含む別の何かをシリアル化する場合、バイナリシリアライザーはXMLシリアライザーよりもはるかに高速です。

私はあなたのコードにこの変更を加えました:

items.Add("asfd");

そして私はこの結果を得る:

Xml: 1219.0541
Bin: 165.0002

違いの一部は、もちろん、XMLファイルがバイナリファイルよりも約10倍大きいことです。

于 2010-08-22T21:38:05.480 に答える
4

例は非常に優れており、質問は興味深いものです (さまざまな並べ替えの初期化はテストの一部と見なされるべきではないため、測定を行う前に Main メソッド自体を少なくとも 1 回実行する必要があるというロバートの意見に同意します)。

そうは言っても、XmlSerializer と BinaryFormatter の重要な違いの 1 つは (明らかなことは別として)、XmlSerializer は参照を追跡しようとしないことです。オブジェクト グラフに同じオブジェクトへの複数の参照がある場合、XML で複数のコピーが取得され、これは逆シリアル化時に適切に解決されません (単一のオブジェクトに戻ります)。サイクルがある場合はさらに悪いことに、オブジェクトをまったくシリアル化できません。これを BinaryFormatter と比較してください。BinaryFormatter は、参照を追跡し、オブジェクト参照の数や種類に関係なく、オブジェクト グラフを確実に再構築します。おそらく、この機能のオーバーヘッドがパフォーマンスの低下の原因でしょうか?

XmlSerializer ではなく BinaryFormatter を使用する主な理由は、シリアル化/逆シリアル化のパフォーマンスではなく、出力のサイズです。(テキストを構築するオーバーヘッドはそれほど大きくありません。高価なのはその xml テキストの転送です。)

于 2010-08-22T23:49:36.133 に答える