Как стать автором
Обновить

Комментарии 33

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Компактный сериализатор для кэша
Сначала прочитал «Компактный стерилизатор для кошек».
Доктор, что со мной?

Кошки они такие. Могут везде начать мерещиться...

Для бенчмарков: https://github.com/dotnet/BenchmarkDotNet.
Для еще большего ускорения можно поменять свойства на поля.
Спасибо за статью, отличная работа.

Благодарю!

Я тоже рекомендую этот BenchmarkDotNet. Работать с ним одно удовольствие :)

Не приходилось раньше слышать. Посмотрю внимательнее, спасибо.

И ещё в сторону ProtoBuf от Гугла можно. Структуры он компактно описывает, но гзипом поверх него все равно бывает полезно пройтись.


Опять же, есть в реализации для всего, можно с фронтом данными обмениваться.

Да, тоже посмотрю. (Удивительно, что даже для c# есть). Но любой «общий» формат сериализации предусматривает запись хоть каких-то, но метаданных. Тут идея была, что при аккуратном обращении со стабильным форматом классов можно попробовать обойтись вовсе без них.
Сравните с Nfx.Slim
Возможно, попробую позже. Сейчас среда слегка разломана, и есть более актуальные задачи. Насколько я понимаю, Nfx всё-таки под более общие и сложные задачи проектировался, вариант в статье ориентирован на быструю сериализацию, но очень простых объектов.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Было бы интересно прочитать в виде статьи или хотя бы глянуть на образчик
Мне бы тоже было интересно глянуть на код примера.
Но в целом да, такой подход может быть даже удобнее, когда исходники сериализуемых классов доступны и находятся в том же солюшене. Если в другом/разделяются с другими командами — уже могут быть трудности. Опять же, может всё-таки возникнуть потребность создать десериализатор для старого варианта объекта, который только в виде сборки сохранился. Всё впрочем, зависит от задачи, конечно, и как работа в целом построена.
T4 у нас использовался для сериализации в другом месте, не знаю, почему он в первую очередь в голову не пришёл.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Отимизация действительно получилась неплохая. В чём она, если не секрет?
При таком подходе, однако, могут возникнуть проблемы на этапах разработки и сборки, а MsBuild/TfsBuild и динамичный состав команды порой приносят немало боли. Надо обеспечить процесс так, чтобы dll-ка на момент запуска шаблона уже лежала в нужном месте и с нужной версией. Если понадобится добавить ещё сборки, или изменить условие фильтрации — надо каждый раз править шаблон и проверять, чтобы ни для кого из нужных классов сериализаторы не потерялись. Плюс условие выбора классов может не выражаться так просто, а кода в итоге получается много, методы SerializerHelper для каждого из них дублируются (хотя это как раз решаемо). Кто-то может не сообразить, что сериализатор автогенерированный, и руками подхачить (MS обычно на такие случаи предупреждения в начале файла пишет). Если сериализуемых классов не очень большое количество, написание просто EmitSerializer<TheClass> может быть гибче, и не нужно заморачиваться, откуда класс взялся — лишь бы он был в используемых пространствах имен.
Но выигрыш производительности 0.0013/0.0027, повторюсь, интригует. Это именно за счёт T4 или изменений самого способа сериализации?
НЛО прилетело и опубликовало эту надпись здесь
Да, если такой подход настроен и привычен, он определённо удобнее :)
С вашего позволения к себе на гитхаб код про T4 добавлять не буду, чтобы не вносить путаницу (да вы, наверно, и не хотите). Если нужно — выложите где-нибудь у себя, авторских претензий на свои куски кода у меня нет.
НЛО прилетело и опубликовало эту надпись здесь

Ещё один хороший вариант — вместо Reflection.Emit использовать System.Lync.Expression.Compile()

ЕМНИП он в два раза медленнее, при сравнимых затратах на инициализацию.
ничуть — оно компилируется в точно такой же IL код, что и Emit… только если что-то не так будет с генерацией — ошибка будет понятной, прямо на вызове Compile(), в отличие от Emit, который, в теории, может дать runtime ошибку.
Я сейчас не помню деталей, но код генерируется не совсем такой.
В качестве пруфа могу дать вот эту ссылку, там Emit в 4 раза быстрее CompiledExpressionTree.

ExpressionTree мне помогли в схожей задаче тем, что давали доступ к private полям, плюс проще кодировалась валидация.

посмотрел статью…
По скорости там в статье по ссылке есть сравнение — у них в 2-3 раза получилось медленнее, чем Native доступ (а в случае IL Emit тоже будут задержки). Кроме того, они несколько неправильный код генерировали…
Если будет время — сегодня/завтра напишу бенчмарк и выложу код/результаты.
Nuget-пэкедж protobuf-net делает примерно тоже самое, но протестирован и поддерживается.
Скорость такая же примерно. Поддерживает модификацию схемы с обратной совместимостью (на основе нумерации полей).

А ещё и имплементирует общеизвестный «стандарт» сериализации.
Круто, буду в курсе.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории