Как повысить производительность службы .net wcf

Я переношу загруженное процессором приложение .net 4.0 для Windows в службу .net 4.0 wcf. В основном я просто импортировал классы .net в службу wcf.

Все работает хорошо, за исключением производительности в службе wcf - задача, которая занимает 6267947 тиков (2539 мс), использует 815349861 тиков (13045 мс) в службе aspx.net wcf, работающей локально на той же машине разработки.

Я уже загрузил сервис + тестовый клиент в appharbor, где производительность такая же плохая, как на моей локальной машине - ссылка на мое тестовое приложение: http://www.wsolver.com. Любые идеи о том, как я могу улучшить производительность?


person Muleskinner    schedule 19.02.2012    source источник
comment
Какие работы выполняет ваша служба?   -  person Johnny Graber    schedule 19.02.2012
comment
@Johnny Graber это решатель Scrabble. он загружает большой словарь в структуру дерева в памяти, где происходит много поиска   -  person Muleskinner    schedule 19.02.2012
comment
Фактический код doing должен занимать столько же времени. Переход на WCF должен повлиять только на проблемы с транспортом, если вы не используете контекст синхронизации и т. д. Можете ли вы уточнить: где измеряется это время? делать код? Или транспорт? Или...?   -  person Marc Gravell    schedule 19.02.2012
comment
@Marc Gravell Транспорт минимален, но в любом случае - эталон измеряется в одном и том же месте в обеих ситуациях, т.е. делать код. Может ли быть так, что службе не выделено достаточно памяти для хранения словаря?   -  person Muleskinner    schedule 19.02.2012
comment
Я нажал ссылку на ваш тестовый сайт 3 раза, и все 3 запроса заняли от 2,1 до 2,5 секунд, что, как вы сказали, является хорошей метрикой (2539 мс). Вы обращались к своему сервису WCF несколько раз и выбрасывали самое низкое и самое высокое число, чтобы получить среднее значение? Если вы просто нажмете его один раз, то я могу увидеть, что 1-е попадание занимает 13 секунд, особенно если оно было размещено на IIS и 1-е попадание.   -  person CodingWithSpike    schedule 20.02.2012
comment
@ rally25rs В моем тестовом примере, который занял около 13 секунд для службы и 2,5 секунды для приложения Windows, было больше букв стойки, чем по умолчанию (извините, если это неясно из вопроса)   -  person Muleskinner    schedule 20.02.2012
comment
Вы загружаете структуру данных при каждом запросе? Если это так, вам следует загрузить его только один раз в Application_Start().   -  person friism    schedule 20.02.2012
comment
@friism так! кэширование словаря в application_start по какой-то причине улучшило производительность, теперь служба wcf работает так же быстро, как и приложение Windows локально — онлайн-версия apphb примерно в три раза медленнее. Я предполагаю, что это связано с назначенными ресурсами процессора   -  person Muleskinner    schedule 21.02.2012
comment
@Muleskinner Отлично, рад, что помог. Инициализация структуры данных (если это дорого) только один раз в Application_Start() значительно улучшит производительность по сравнению с выполнением инициализации в каждом запросе.   -  person friism    schedule 21.02.2012
comment
@Muleskinner У меня есть это предложение в качестве ответа ниже, пожалуйста, примите его, если вы считаете, что это решило проблему.   -  person friism    schedule 21.02.2012


Ответы (5)


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

person friism    schedule 20.02.2012
comment
Спасибо, не могли бы вы сказать, что несоответствие производительности при локальном запуске службы wcf по сравнению с запуском ее онлайн в appharbor (в 3 раза медленнее при расчете, без учета сетевого трафика) можно объяснить отсутствием достаточных ресурсов ЦП в appharbor. Если да, можно ли оптимизировать производительность за счет привлечения дополнительных работников? - person Muleskinner; 21.02.2012
comment
Приобретение дополнительных работников не увеличит время ответа на отдельные запросы, но повысит общую пропускную способность запросов, поскольку вы получите дополнительный параллелизм. Мы думаем, стоит ли нам добавлять более мощных отдельных рабочих. Возможно, вы захотите подумать, уместна ли такая ресурсоемкая обработка в синхронных запросах и, возможно, лучше перенести ее в асинхронный запрос AJAX. - person friism; 21.02.2012

Проверьте любые зависимости от вашего сервиса, которые могут быть созданы во время запроса. К ним относятся зависимости конструктора и зависимости поля/свойства. Может быть, один из них вызывает задержку? Если это так, рассмотрите возможность использования синглтона для создания экземпляра долговременного класса.

Вы подтвердили, что последующие запросы по-прежнему вызывают задержку?

Также создайте новый сервис группы, который делает что-то простое, например Datetime.Now.toString(), и посмотрите, есть ли у него такая же проблема.

person reach4thelasers    schedule 19.02.2012

Пожалуйста, ознакомьтесь со статьями и техническими документами ниже. Я думаю, что они должны дать вам достаточно конкретных соображений производительности для изучения и, вероятно, некоторые очень практичные настройки для настройки, оптимизации или изменения.

Настройка производительности служб WCF

Оптимизация производительности веб-службы WCF

Использование ServiceThrottlingBehavior для управления производительностью службы WCF

Транспортные квоты

Оптимизация производительности IIS

Обзор производительности ASP.NET

Сравнение производительности Windows Communication Foundation (WCF) с существующими технологиями распределенной связи

person krisragh MSFT    schedule 19.02.2012
comment
Я думаю, что это хороший список ссылок, но не могли бы вы рассказать о некоторых конкретных методах, которые вы использовали, которые вы нашли полезными? - person MatthewJ; 20.02.2014

Я бы сделал полный дамп памяти за 13 секунд (или несколько с помощью procdump), а потом реально посмотрел, что происходит в процессе (windbg и sos.dll). Затем вы можете сузить, какой код является виновником.

person Davin Tryon    schedule 19.02.2012

Я так понимаю, дерево словарей загружается только один раз, в кеш? Вы же не загружаете его при каждом звонке?

person Duncan    schedule 19.02.2012
comment
он загружает каждый вызов в данный момент (это первый прототип), но это не проблема. Время загрузки Trie занимает 417 мс. - person Muleskinner; 19.02.2012