Статьи

Сериализация Windows Phone 7: сравнение

В этом посте я собираюсь сравнить несколько способов сериализации в приложениях Windows Phone 7. Я покажу, сколько времени потребовалось для сериализации и десериализации объекта и какого размера имел выходной поток. Сравнение включает Xml сериализацию , DataContract сериализацию , DataContract JSON сериализацию и мою бинарную сериализацию для Windows Phone 7 , Json.NET сериализации , sharpSerializer . Я описал каждый из этих типов в моих предыдущих постах.

Тесты проводились с использованием устройства Windows Phone 7 от LG.

Вступление

Прежде чем сравнивать несколько типов сериализации Windows Phone 7 (и Silverlight), я бы хотел сказать, что у каждого типа есть свои преимущества и недостатки для определенных типов задач. Это означает, что для хранения объектов в изолированном хранилище один тип лучше другого, но когда дело доходит до Windows Communication Foundation (WCF), то это может быть наоборот. Итак, прежде всего вам нужно определить свою задачу . Что касается моего сравнения, моей миссией было найти наиболее подходящий способ сериализации для хранения объектов в изолированном хранилище. Из-за того, что устройства Windows Phone 7 имеют очень ограниченный объем памяти (размер файла), это был важный критерий в моих тестах.

Образец объекта

Сначала я создал образец класса, который поддерживается каждым типом сериализации, упомянутым в этом посте. Вот код для этого класса:

[DataContract]
public class SampleData
{
    [XmlElement]
    [DataMember]
    public string ContentText { get; set; }
 
    [XmlElement]
    [DataMember]
    public List<int> SomeItems { get; set; }
 
    public void Fill()
    {
        StringBuilder sb = new StringBuilder();
        for (int index = 0; index < 1000; index++)
        {
            sb.Append("sometext sometext\n");
        }
        ContentText = sb.ToString();
 
        SomeItems = new List<int>();
        for (int index = 0; index < 1000; index++)
        {
            SomeItems.Add(index);
        }
    }
}

Тестирование XML-сериализации

Я начал свое путешествие с XML-сериализации с использованием XmlSerializer . Я создал метод для тестирования (см. Код ниже) и запускаю его ровно пять раз. Длина объекта потока была 48070 байт.

public void TestXMLSerializer(SampleData sd)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // time in milliseconds
        double serTime = TestMethod(() =>
            XMLSerializerHelper.Serialize(ms, sd));
        long size = ms.Length;
        ms.Position = 0;
        double deSerTime = TestMethod(() =>
            XMLSerializerHelper.Deserialize(ms, typeof(SampleData)));
    }
}

Вы можете увидеть результаты XML-сериализации для Windows Phone 7 ниже. Этот тип сериализации довольно быстрый, но размер потока довольно велик.

Тип Время (в миллисекундах) Средний
Сериализация 309 309 306 310 304 307,6
Десериализация 191 188 187 189 193 189,6

Тестирование сериализации DataContract

Затем я протестировал сериализацию DataContract . Еще раз я создал метод для тестирования (код ниже). Длина потока составила 42165 байт.

public void TestDataContractSerialization(SampleData sd)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // time in milliseconds
        double serTime = TestMethod(() =>
            DataContractSerializationHelper.Serialize(ms, sd));
        long size = ms.Length;
        ms.Position = 0;
        double deSerTime = TestMethod(() =>
            DataContractSerializationHelper.Deserialize(ms, typeof(SampleData)));
    }
}

Посмотрите на результаты сериализации DataContract в таблице ниже. Вероятно, один из худших результатов в этом сравнении. Размер потока немного лучше, чем размер потока во время сериализации XML.

Тип Время (в миллисекундах) Средний
Сериализация 469 471 469 478 471 471,6
Десериализация 190 196 198 200 193 195,4

Тестирование DataContract JSON-сериализации

Другим конкурентом была сериализация DataContract JSON . Метод тестирования показан ниже. Длина потока составила 22922 байта.

public void TestDataContractJSONSerialization(SampleData sd)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // time in milliseconds
        double serTime = TestMethod(() =>
            DataContractJSONSerializationHelper.Serialize(ms, sd));
        long size = ms.Length;
        ms.Position = 0;
        double deSerTime = TestMethod(() =>
            DataContractJSONSerializationHelper.Deserialize(ms, typeof(SampleData)));
    }
}

Результаты для сериализации DataContract JSON (таблица ниже) лучше, чем для сериализации DataContract, особенно при сравнении размера потока.

Тип Время (в миллисекундах) Средний
Сериализация 494 494 492 490 497 493,4
Десериализация 189 188 197 188 189 190,2

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

Наконец, моя пользовательская двоичная сериализация для Windows Phone 7 показала лучшие результаты в этом сравнении. Проверьте метод, который я использовал для тестирования ниже. Длина потока составила 22007 байт.

public void TestBinarySerialization(SampleData sd)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // time in milliseconds
        double serTime = TestMethod(() =>
            BinarySerializationHelper.Serialize(ms, sd));
        long size = ms.Length;
        ms.Position = 0;
        double deSerTime = TestMethod(() =>
            BinarySerializationHelper.Deserialize(ms, typeof(SampleData)));
    }
}

Вот результаты, которые я получил для моей пользовательской двоичной сериализации. Время десерилизации поражает. Также размер потока меньше, чем в сериализации DataContract JSON.

Тип Время (в миллисекундах) Средний
Сериализация 123 130 123 124 123 124,6
Десериализация 21 22 21 21 22 21,4

Тестирование сериализации Json.NET

После нескольких комментариев, касающихся Json.NET, я решил добавить его в свое сравнение. Я также создал учебник, описывающий, как сериализовать и десериализовать объекты, используя подход Json.NET . Длина потока была не такой большой, как для сериализаций на основе XML, всего 22922 байта (аналогично размеру потока сериализации DataContract JSON).

public void TestJSONNETSerialization(SampleData sd)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // time in milliseconds
        double serTime = TestMethod(() =>
            JSONNETSerializationHelper.Serialize(ms, sd));
        long size = ms.Length;
        ms.Position = 0;
        double deSerTime = TestMethod(() =>
        {
            JSONNETSerializationHelper.Deserialize(ms, typeof(SampleData));
        });
    }
}

Результаты (таблица ниже) немного лучше по сравнению с типами сериализации DataContract и DataContractJSON, но нет шансов превзойти результаты пользовательской двоичной сериализации.

Тип Время (в миллисекундах) Средний
Сериализация 451 421 411 415 420 423,6
Десериализация 133 132 131 137 131 132,8

Тестирование sharpSerializer

Лично мне этот csharpSerializer очень нравится, и результаты тестов для этой сериализации выглядят довольно многообещающе. Размер потока для двоичной сериализации csharpSerializer составлял 28177 байт, а для сериализации XML csharpSerializer — 54292 байта.

public void TestSharpSerializer(SampleData sd)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // time in milliseconds
        double serTime = TestMethod(() =>
            SharpSerializerHelper.Serialize(ms, sd));
        long size = ms.Length;
        ms.Position = 0;
        double deSerTime = TestMethod(() =>
        {
            SharpSerializerHelper.Deserialize(ms);
        });
    }
}

Я проверил оба типа SharpSerializer XML и двоичные. Результаты двоичной сериализации довольно хорошие, результаты XML-вывода почти такие же, как и для XMLSerializer.

Бинарный (sharpSerializer)

Тип Время (в миллисекундах) Средний
Сериализация 250 250 247 247 249 248,6
Десериализация 60 60 61 61 60 60,4

XML (sharpSerializer)

Тип Время (в миллисекундах) Средний
Сериализация 278 283 280 286 278 281
Десериализация 179 177 179 185 176 179,2

 

Окончательные результаты

Ниже приводится таблица окончательных результатов для сравнения этих четырех способов сериализации для Windows Phone 7 (и, возможно, Silverlight). По этим результатам у нас чистый победитель: двоичная сериализация . Возможно, моя реализация двоичной сериализации еще не идеальна, но все же она показывает лучшие результаты в моих сравнениях и тестах.

Тип   Сериализация (мс) Десериализация (мс) Размер (байт)
Пользовательская двоичная сериализация   124,6 21,4 22007
sharpSerializer Двоичная Сериализация   248,6 60,4 28177
sharpSerializer XML-сериализация   281 179,2 54292
XMLSerializer   307,6 189,6 48070
Сериализация Json.NET   423,6 132,8 22922
Сериализация DataContract JSON   493,4 190,2 22922
Сериализация DataContract   471,6 195,4 42165

 

Версия для печати

 

Резюме

Как я уже говорил ранее, в разработке много конкретных задач, и каждая из них требует особого подхода. С моей точки зрения, если задача заключается в хранении сериализованных данных в изолированном хранилище, то я бы использовал sharpSerializer (Binary) или мою пользовательскую двоичную сериализацию, поскольку размер сериализованных данных мал. Также скорость сериализации и десериализации довольно хороша. Когда ваша задача требует передачи данных по сети (например), я бы выбрал тип среди сериализаций на основе XML или сериализаций на основе JSON. Важным моментом является то, что результаты тестов, создаваемых эмулятором Windows Phone 7 и настоящим устройством Windows Phone 7, сильно отличаются

Исходный код

Вы можете попробовать запустить эти тесты на ваших собственных пользовательских объектах. Вот исходный код для этого:
КОД ИСТОЧНИКА

Источник:  http://www.eugenedotnet.com/2010/12/windows-phone-7-serialization-comparison/