Генератор сериализаторов на основе Expression Trees
От: SuhanovSergey  
Дата: 25.03.14 16:35
Оценка:
Выяснилось, что мой сервис тратит много времени на сериализацию в json. Профилирование показывает, что сериализатор читает значения полей через медленный Type.InvokeMember. Идельный сериализатор должен читать поля без reflection. Т.е. сериализатор должен быть сгенерированным под конкретные типы. Подумалось, что это можно сделать незаметно для пользователя сериализатора с помощью expression trees. Я ожидал быстро найти реализацию этой идеи в интернете, но кроме какой-то наколеенной поделки (http://monotorrent.blogspot.se/2009/12/expression-trees-serializing-your-data.html) ничего не нашёл. Идея чем-то плоха или плохо искал?
Re: Генератор сериализаторов на основе Expression Trees
От: andyag  
Дата: 25.03.14 16:48
Оценка:
Здравствуйте, SuhanovSergey, Вы писали:

SS>Выяснилось, что мой сервис тратит много времени на сериализацию в json. Профилирование показывает, что сериализатор читает значения полей через медленный Type.InvokeMember. Идельный сериализатор должен читать поля без reflection. Т.е. сериализатор должен быть сгенерированным под конкретные типы. Подумалось, что это можно сделать незаметно для пользователя сериализатора с помощью expression trees. Я ожидал быстро найти реализацию этой идеи в интернете, но кроме какой-то наколеенной поделки (http://monotorrent.blogspot.se/2009/12/expression-trees-serializing-your-data.html) ничего не нашёл. Идея чем-то плоха или плохо искал?


Если не секрет, каков примерно характер транзакций и передаваемых данных?
Re: Генератор сериализаторов на основе Expression Trees
От: andyag  
Дата: 25.03.14 16:49
Оценка:
Здравствуйте, SuhanovSergey, Вы писали:

SS>Выяснилось, что мой сервис тратит много времени на сериализацию в json.


"Тратит много времени на сериализацию" или "больше всего времени уходит на сериализацию"?
Re[2]: Генератор сериализаторов на основе Expression Trees
От: SuhanovSergey  
Дата: 25.03.14 16:58
Оценка:
A>Если не секрет, каков примерно характер транзакций и передаваемых данных?
Ответы REST сервиса. Объекты с полями типа строк, чисел, под-объектов. Средний размер ответа около 1k.

A>"Тратит много времени на сериализацию" или "больше всего времени уходит на сериализацию"?

40% процентов CPU sample-ов попадает в сериализатор. Хотелось бы, видеть распределеение, где CPU тратился именно на бизнес логику, а не на сериализацию.
Re[3]: Генератор сериализаторов на основе Expression Trees
От: andyag  
Дата: 25.03.14 17:05
Оценка:
Здравствуйте, SuhanovSergey, Вы писали:

A>>Если не секрет, каков примерно характер транзакций и передаваемых данных?

SS>Ответы REST сервиса. Объекты с полями типа строк, чисел, под-объектов. Средний размер ответа около 1k.

A>>"Тратит много времени на сериализацию" или "больше всего времени уходит на сериализацию"?

SS>40% процентов CPU sample-ов попадает в сериализатор. Хотелось бы, видеть распределеение, где CPU тратился именно на бизнес логику, а не на сериализацию.

Совершенно случайно, у вас там не WCF ли, с его родным сериализатором JSON?
Re[4]: Генератор сериализаторов на основе Expression Trees
От: SuhanovSergey  
Дата: 26.03.14 09:11
Оценка:
Здравствуйте, andyag, Вы писали:

A>Совершенно случайно, у вас там не WCF ли, с его родным сериализатором JSON?


WebAPI с его родным Newtonsoft.Json
Re: Генератор сериализаторов на основе Expression Trees
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 27.03.14 21:37
Оценка:
Здравствуйте, SuhanovSergey, Вы писали:

SS>но кроме какой-то наколеенной поделки (http://monotorrent.blogspot.se/2009/12/expression-trees-serializing-your-data.html) ничего не нашёл.


Из интереса попробовал сделать, как предлагает этот товарищ. Никакого ускорения не добился. Работает не быстрее даже простого перебора свойств с помощью Type.GetProperties().

Собственно, это только подтвердило имевшиеся у меня подозрения, что тут особо ничего не соптимизируешь.

В свое время пытался кэшировать сериализующие делегаты: см. метод GetEntityToDocumentConvertorFunctor. И тоже с удивлением обнаружил отсутствие ускорения.

Так что идея не то чтобы плоха, а вроде как бы и ненужная
Re[2]: Генератор сериализаторов на основе Expression Trees
От: SuhanovSergey  
Дата: 28.03.14 08:57
Оценка: +1
Здравствуйте, scale_tone, Вы писали:

SS>>но кроме какой-то наколеенной поделки (http://monotorrent.blogspot.se/2009/12/expression-trees-serializing-your-data.html) ничего не нашёл.

_>Из интереса попробовал сделать, как предлагает этот товарищ. Никакого ускорения не добился. Работает не быстрее даже простого перебора свойств с помощью Type.GetProperties().

Эту поделку не пробовал. Не искючено, что она глючная.

Попробовал по быстрому реализовать идею, применительно к своей проблеме — сериализация в json.
— Вариант 1. Использование JsonSerializer.Serialize(JsonWriter, value). Это то, что делает webapi по умолчанию.
— Вариант 2. Запись в JsonWriter с помощю кода, сгенерированного для конкретного типа value.

(2) работает в три раза быстрее.

Профайлер показывает, что тормозит в рарианте 1:
— строковые представления enum-ов получаются через enumValue.ToString(). В (1) они получаются через сгенерированную инструкцию switch.
— поля читаются через reflection. (2) читает напрямую.
— (1) усердно занимается json escaping. В (2) названия полей и строковые значение enum-ов пишутся в "сыром" виде. Это константы, их значения можно провалидировать/проэскейпировать заранее.

Думаю, можно ускорить ещё немного, если дать подсказки генератору кода. Например, если известно, что значения каких-то полей гарантированно не потребуют эскепирования, то поля можно пометить атрибутом, и сериализатор будет писать из в сыром виде.
Re[3]: Генератор сериализаторов на основе Expression Trees
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 28.03.14 20:08
Оценка:
Здравствуйте, SuhanovSergey, Вы писали:

SS>- Вариант 2. Запись в JsonWriter с помощю кода, сгенерированного для конкретного типа value.


SS>- поля читаются через reflection. (2) читает напрямую.


Так как именно? Покажите ж код!
Re[4]: Генератор сериализаторов на основе Expression Trees
От: SuhanovSergey  
Дата: 30.03.14 08:59
Оценка: 6 (1)
Здравствуйте, scale_tone, Вы писали:

_>Здравствуйте, SuhanovSergey, Вы писали:


SS>>- Вариант 2. Запись в JsonWriter с помощю кода, сгенерированного для конкретного типа value.


SS>>- поля читаются через reflection. (2) читает напрямую.


_>Так как именно? Покажите ж код!


Через код, сгенерированный Expression.Property().

Собственно код.
Re[5]: Генератор сериализаторов на основе Expression Trees
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 05.04.14 09:43
Оценка:
Здравствуйте, SuhanovSergey, Вы писали:

SS>Собственно код.


Попробовал. Да, действительно, у Вас JSON быстрее генерится. Особенно заметно на ветвистых деревьях объектов. Подумаем, не заюзать ли у себя...


В моем случае (сериализация простых объектов в Amazon.DynamoDb.DocumentModel.Document), правда, выигрыша от Expression.Property() все равно не получается
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.