2013-09-06 2 views
4

У меня есть служба WCF, которая выполняет поиск и возвращает список достаточно сложных объектов клиенту. Это система EAV, поэтому каждый возвращаемый объект имеет список прикрепленных значений, размер которых зависит от размера объекта.Медленная сериализация ответа WCF с использованием DataContractSerializer

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

К сожалению, клиент не получает ответ до 15-20 секунд после того, как я закончил с ним. Общий размер ответа составляет около 250 кб, поэтому он довольно маленький. Это передается по локальной сети в течение минуты, и я попытался отключить брандмауэр и антивирус, чтобы убедиться, что ни один из них не вмешивается.

Я заметил, однако, что если ответ был значительно меньше, например, удалив поля, прикрепленные к каждому объекту, ответ был намного быстрее. Я также попытался пройти через локально размещенную (IIS) копию службы, и после прохождения окончательного заявления return все еще потребовалось еще 15 секунд, чтобы добраться до локального клиентского приложения.

Я использую basicHttpBinding, поскольку служба будет потребляться как .Net, так и PHP-клиентами.

Теперь, может ли кто-нибудь предложить способ, я могу подтвердить, что это действительно так? И как я могу исправить вредоносное медленное время сериализации?

Edit:

Чтобы уточнить, я пометил каждый класс с [DataContract] атрибута и каждого свойства с [DataMember] - WCF обрабатывает сериализацию, когда я вернуть данные. В этом случае это список типа Entity (пользовательский класс, который содержит список значений

Edit 2:.

Я проверил скорость DataContractSerializer и она занимает около 15 секунд, чтобы написать список из 65 возвращенных объектов в простой поток памяти. Это кажется смешным, и я не уверен, что изменилось, чтобы сделать его настолько болезненно медленным.

+0

Какой код вы используете для сериализации? Вы использовали Fiddler, чтобы увидеть, когда приходит первый байт. Какой класс вы сериализуете? Вы сериализуете список объектов? – Aron

+0

Отредактировал вопрос, чтобы включить информацию, которую вы просили. – Maloric

+0

Ой, и я не пробовал Fiddler - посмотрим, что сейчас. – Maloric

ответ

4

Я понял это, и это довольно неловко.

Во время тестирования скорости DataContractSerializer я использовал список из 65 продуктов, которые возвращались из моего поиска. Я решил загружать все продукты (около 600) в базу данных и затем сериализовывать их в памяти, но получил несколько исключений из памяти, поэтому вместо этого начал записывать результаты в текстовый файл.

Получается, что текстовый файл был 1,5 ГБ, что примерно в 3 раза превышает размер всей базы данных. Для сериализации потребовалось 17 секунд. Так что, на самом деле, это была чертовски хорошая работа.Что происходит, так это то, что каждый продукт может иметь список прикрепленных объектов, и они также загружаются. Поскольку они сериализованы, эти объекты дублируются, если они существуют в базе данных только один раз.

Наряду с удалением тонны метаданных, которые не нужны клиенту, мне удалось получить список из 50 продуктов (с 194 МБ) до всего лишь 3 МБ. (обновление: в эти выходные я получил список 1,5 ГБ до 66 МБ).

Мораль истории? Слушайте сообщество. Все остальные сказали мне, как быстро DataContractSerializer, поэтому, когда мне показалось, что мне мешает, я должен был обвинить себя вместо DataContractSerializer.

UPDATE:

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

0

Нужно ли использовать DataContractSerializer? Я нашел DataContractSerializer при отправке большие объемы данных очень медленные, потери производительности не при сериализации, а при десериализации.

Мы переключились на двоичную сериализацию, которая намного быстрее, но может быть несовместима с вами PHP-клиентами. Вы можете написать компонент, который может быть повторно использован клиентом, обрабатывает десериализацию для вас, но вы ударите его для всех клиентов non .net.

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