Я очень часто читал, что 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
Пример довольно хороший, а вопрос интересный (я согласен с Робертом, что вам следует запустить сам метод Main хотя бы один раз, прежде чем проводить какие-либо измерения, поскольку инициализация переменных разного рода не должна считаться частью теста)
При этом одно ключевое различие между XmlSerializer и BinaryFormatter (помимо очевидного) заключается в том, что XmlSerializer не пытается отслеживать ссылки. Если ваш граф объектов имеет несколько ссылок на один и тот же объект, вы получите несколько копий в XML, и это не будет разрешено должным образом (обратно в один объект) при десериализации. Хуже того, если у вас есть циклы, объект вообще не может быть сериализован. В отличие от BinaryFormatter, который действительно отслеживает ссылки и надежно восстанавливает граф объекта независимо от того, сколько и какого рода ссылок на объект у вас может быть. Возможно, накладные расходы на этот механизм объясняют более низкую производительность?
Основной причиной использования BinaryFormatter вместо XmlSerializer является размер выходных данных, а не производительность сериализации/десериализации. (Накладные расходы на создание текста не так уж велики, дорого обходится транспортировка этого xml-текста)
.Поскольку вы сериализуете объект, у которого нет свойств.
Если вы сериализуете что-то другое, что на самом деле содержит некоторые данные, например, строку, бинарный сериализатор работает намного быстрее, чем XML-сериализатор.
Я внес это изменение в ваш код:
items.Add("asfd");
и получил такой результат:
Xml: 1219.0541
Bin: 165.0002
Отчасти разница, конечно же, в том, что файл XML примерно в десять раз больше, чем двоичный файл.