Сериализация данных

84

Сериализация (serialization) - это операция преобразования объекта в формат, пригодный для записи на диск или отправки в сеть. Десериализация (deserialization) - это операция восстановления объекта из сериализованного представления. Например, хеш-таблица может быть сериализована в массив записей ключ/значение.

Тестирование производительности средств сериализации

В состав .NET Framework входит несколько универсальных средств сериализации, с помощью которых можно выполнять сериализацию и десериализацию пользовательских типов. В этом разделе оцениваются достоинства и недостатки каждого из них и приводятся результаты тестирования производительности и компактности получаемых данных.

Для начала познакомимся с имеющимися средствами сериализации:

XmlSerializer из пространства имен System.Xml.Serialization
  • сериализует текстовые и двоичные данные в формат XML;

  • сериализует дочерние объекты, но не поддерживает циклические ссылки;

  • сериализует только общедоступные поля и свойства, за исключением тех, что явно исключены из сериализации;

  • для повышения эффективности использует механизм рефлексии (Reflection) только единожды, когда генерирует код сборки сериализации, - для предварительного создания сборки сериализации можно использовать инструмент sgen.exe;

  • позволяет настраивать схему XML;

  • требует знания всех типов, участвующих в сериализации: эта информация выводится автоматически, за исключением случаев, когда используются унаследованные типы.

BinaryFormatter из пространства имен System.Runtime.Serialization.Formatters.Binary
  • сериализует в закрытый двоичный формат, который распознается только классом BinaryFormatter;

  • используется механизмом .NET Remoting, но может использоваться как самостоятельный инструмент сериализации;

  • сериализует не только общедоступные поля;

  • распознает циклические ссылки;

  • не требует предварительного знания типов сериализуемых объектов;

  • определения сериализуемых типов должны быть отмечены атрибутом [Serializable].

SoapFormatter из пространства имен System.Runtime.Serialization.Formatters.Soap
  • своими возможностями напоминает BinaryFormatter, но сериализует в формат SOAP XML, более пригодный для обмена данными с другими системами, но менее компактный;

  • не поддерживает обобщенные типы и обобщенные коллекции и, соответственно, не рекомендуется к использованию в последних версиях .NET Framework.

DataContractSerializer из пространства имен System.Runtime.Serialization
  • сериализует текстовые и двоичные данные в формат XML;

  • используется механизмом WCF, но может использоваться как самостоятельный инструмент сериализации;

  • сериализует типы и поля, отмеченные атрибутами [DataContract] и [DataMember]: если класс отмечен атрибутом [Serializable], сериализоваться будут все поля этого класса;

  • требует знания всех типов, участвующих в сериализации: эта информация выводится автоматически, за исключением случаев, когда используются унаследованные типы;

NetDataContractSerializer из пространства имен System.Runtime.Serializatio
  • напоминает DataContractSerializer, но встраивает в сериализованные данные информацию о типе;

  • не требует предварительного знания типов сериализуемых объектов;

  • требует доступа к сборкам, содержащим объявления сериализуемых типов.

DataContractJsonSerializer из пространства имен System.Runtime.Serialization
  • напоминает DataContractSerializer, но сериализует в формат JSON вместо XML.

На рисунке ниже представлены результаты тестирования производительности средств сериализации, описанных выше. Некоторые из них тестировались дважды - для сериализации в текстовый и двоичный формат. В ходе тестирования выполнялась сериализация и десериализация очень сложного графа объектов, включающего 3600 экземпляров пяти типов и имеющего древовидную структуру. Каждый тип имел поля типов string и double, а также массивы элементов этих типов. Циклические ссылки отсутствовали в тестовом наборе данных, потому что не все средства сериализации поддерживают их; однако те, что поддерживают их, обрабатывали данные существенно медленнее при их наличии.

Результаты тестирования производительности средств сериализации в операций/сек

Результаты тестирования, представленные здесь, были получены в версии .NET Framework 4.5 RC, показывающей немного более высокую производительность в сравнении с версией .NET Framework 3.5 в тестах сериализации в двоичный формат XML, но в остальных тестах производительность практически ничем не отличалась.

Из результатов тестирования можно заключить, что самыми быстрыми являются DataContractSerializer и XmlSerializer, при сериализации в двоичный формат XML.

Затем мы сравнили эти же средства по объему данных, полученных в результате сериализации (показано на рисунке ниже). Здесь можно выделить несколько инструментов, очень близких по этому показателю. Скорее всего это обусловлено тем, что наибольший объем данных был сосредоточен в строках, которые сериализуются в одно и то же представление всеми описываемыми средствами.

Сравнение по объему сериализованных данных

Наиболее компактное представление сериализованных данных дает DataContractJsonSerializer. За ним близко следуют XmlSerializer и DataContractSerializer, при сериализации в двоичный формат. Самое удивительное, пожалуй, что класс BinaryFormatter был превзойден по производительности большинством других средств сериализации.

Сериализация объектов DataSet

Объект DataSet - это кеш в памяти для хранения данных, извлеченных из базы данных с помощью DataAdapter. Он содержит коллекцию объектов DataTable, определяющую структуру базы данных и записи с данными, каждая из которых содержит коллекцию сериализованных объектов. Объекты DataSet чрезвычайно сложны, занимают большие объемы памяти, и требуют значительных вычислительных затрат на сериализацию. Однако многие приложения передают их между своими уровнями.

Ниже приводится несколько советов, следование которым поможет уменьшить накладные расходы, связанные с сериализацией DataSet:

Пройди тесты
Лучший чат для C# программистов