2009-07-07 3 views
8

Я работаю над компактным рамочным приложением и должен повысить производительность. Приложение в настоящее время работает в автономном режиме, сериализуя объекты в XML и сохраняя их в базе данных. Используя инструмент профилирования, я видел, что это было довольно накладные расходы, замедляя приложение. Я подумал, что если бы я переключился на двоичную сериализацию, производительность увеличилась бы, но поскольку это не поддерживается в компактной структуре, я смотрел на protobuf-net. Сериализация кажется более быстрой, но десериализация намного медленнее, и приложение делает больше десериализации, чем сериализация.XML vs Двоичная производительность для сериализации/десериализации

Должна ли бинарная сериализация быть быстрее, и если да, то что я могу сделать, чтобы ускорить работу? Вот отрывок о том, как я использую как XML и двоичную:

XML сериализации:

public string Serialize(T obj) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    MemoryStream stream = new MemoryStream(); 
    XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8); 
    serializer.Serialize(stream, obj); 
    stream = (MemoryStream)writer.BaseStream; 
    return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length)); 
} 
public T Deserialize(string xml) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));    
    return (T)serializer.Deserialize(stream); 
} 

Protobuf внутрисетевые Binary сериализации:

public byte[] Serialize(T obj) 
{ 
    byte[] raw; 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
    Serializer.Serialize(memoryStream, obj); 
    raw = memoryStream.ToArray(); 
    } 

    return raw;    
} 

public T Deserialize(byte[] serializedType) 
{ 
    T obj; 
    using (MemoryStream memoryStream = new MemoryStream(serializedType)) 
    { 
    obj = Serializer.Deserialize<T>(memoryStream); 
    } 
    return obj; 
} 
+0

Я собирался предложить использовать профилировщик ANTS Red-Gate, но он не работает с каркасом Compact (поиск в google «red-gate ants profiler compact») – Kane

ответ

1

Интересные ... мысли:

  • какая версия CF это; 2,0? 3,5? В частности, CF 3.5 имеет Delegate.CreateDelegate, что позволяет Protobuf-сети доступ к свойствам гораздо быстрее, чем в банке в CF 2.0
  • вы аннотирования поля или свойства? Опять же, в CF оптимизация отражения ограничена; вы можете получить Beter производительности в CF 3.5 с свойствами, а с полем единственным вариантом у меня есть доступный FieldInfo.SetValue

Есть целый ряд других вещей, которые просто не существуют в CF, так что есть чтобы пойти на компромиссы в нескольких местах. Для слишком сложных моделей также есть known issue with the generics limitations of CF. Исправлено исправление, но это большое изменение, и он принимает «некоторое время».

Для информации некоторые показатели на регулярной (полной) платформе .NET, сравнивающие различные форматы (включая XmlSerializer и protobuf-net) are here.

+0

Я использую CF2.0, и у меня есть добавлены атрибуты свойств для объектов, которые мне нужны для сериализации. – Charlie

+0

Можно ли попробовать его в CF 3.5 (с двоичным кодом CF 3.5), чтобы убедиться, что это исправление? –

+0

Хорошо, я только что проверил свой тест на CF3.5 и увидел значительное увеличение производительности от CF2; двоичный код выполняется намного быстрее как для сериализации, так и для десериализации. К сожалению, я привязан к CF2, хотя мне, возможно, придется переосмыслить ситуацию. – Charlie

0

Вы пробовали создавать пользовательские классы сериализации для своих классов? Вместо использования XmlSerializer, который является универсальным сериализатором (он создает кучу классов во время выполнения). Для этого есть инструмент (sgen). Вы запускаете его во время процесса сборки и генерируете пользовательскую сборку, которая может использоваться в темпе XmlSerializer.

Если у вас есть Visual Studio, этот параметр доступен на вкладке «Сборка» свойств вашего проекта.

0

Является ли производительность успешной в сериализации объектов или их записи в базу данных? Поскольку писать их, скорее всего, ударит по какой-то медленной памяти, я бы предположил, что это намного больший перфект, чем шаг сериализации.

Имейте в виду, что измерения перфоратора, проведенные Марк Гравелл, проверяют производительность более чем на 1 000 000 итераций.

В каком хранилище вы храните файлы? Являются ли объекты сериализованными в памяти или прямыми для хранения? Как они отправляются в ДБ? Насколько велики объекты? Когда кто-то обновляется, отправляете ли вы все объекты в базу данных или только те, которые были изменены? Вы вообще кешируете что-либо в памяти или перечитываете из памяти каждый раз?

+0

Объекты хранятся в базе данных SQLCe, но я могу ясно видеть, что сериализация и десериализация - это поражение производительности, а не взаимодействие с базой данных. Материал также кэшируется в памяти, но нужно хранить материал в БД, чтобы он мог быть восстановлен между сеансами приложения. – Charlie

5

Я собираюсь исправить себя на этом, Марк Гравалл указал, что первая итерация имеет накладные расходы на создание модели, поэтому я провел несколько тестов, в которых принимало среднее число 1000 итераций сериализации и десериализации для XML и двоичных , Сначала я попробовал свои тесты с v2 в DLL Compact Framework, а затем с v3.5 DLL. Вот что я получил, время в мс:

.NET 2.0 
================================ XML ====== Binary === 
Serialization 1st Iteration  3236  5508 
Deserialization 1st Iteration 1501  318 
Serialization Average   9.826  5.525 
Deserialization Average   5.525  0.771 

.NET 3.5 
================================ XML ====== Binary === 
Serialization 1st Iteration  3307  5598 
Deserialization 1st Iteration 1386  200 
Serialization Average   10.923  5.605 
Deserialization Average   5.605  0.279 
0

XML часто медленно обрабатывает и занимает много места. Было предпринято множество различных попыток решить эту проблему, и самым популярным сегодня, похоже, является просто падение партии в файле gzip, например, с Open Packaging Convention.

W3C показал, что подход gzip является менее оптимальным, и они и различные other groups работают над лучшей двоичной сериализацией, подходящей для быстрой обработки и сжатия, для передачи.

3

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

Следуя этому совету, я увидел значительное улучшение производительности в моем приложении, которое позволило мне продолжить использовать сериализацию XML.

Надеюсь, это поможет.

Смежные вопросы