Я наблюдаю странные проблемы с производительностью - из трех способов доступа к службе WCF:
- самый быстрый один через basicHttp
- netTcp * медленнее и
- netTcp с форматером protoBuff-net немного медленнее , чем basicHttp.
Справочная информация: я унаследовал несколько сложных серверных приложений, выполняя многовычисления и доступ к БД, который вызывается серверной частью нашего внешнего интерфейса (т. е. браузер вызывает A, A вызывает B, B получает данные из SQL, делает некоторые вычисления, возвращает их A, который, как он делает, выполняет еще некоторые вычисления и возвращает ихв браузер).
Мы говорим о производительности части A <-> B. Большая часть данных передается от B к A после получения запроса от A.
WCF размещается самостоятельно (для этого эксперимента).
Служба предоставляется через 3 различные конечные точки:
- basicHttpBinding с messageEncoding = "Text" textEncoding = "utf-8"
- netTcpBinding
- netTcpBinding с protobuf-net
Я написал выделенныйпростой клиент, который создает полезную нагрузку. Он просто вызывает службу, используя 3 разных экземпляра одного и того же клиента WCF (по одному на каждую конечную точку).
Вызовы выполняются в цикле (101 итерация), время первой итерации отбрасывается, время берется с экземпляром Stopwatch.
Однопоточные, синхронные вызовы, каждый вызов начинается только после того, как был завершен предыдущий, и проверены возвращенные объекты.
Вызываемая служба (B) выполняет одинаковую обработку для каждого вызова и возвращает данныеидентичен для каждого вызова и для каждой конечной точки.
Каждый запрос имеет небольшое количество примитивных типов, идущих от клиента к B, затем B возвращает List<T>
с ~ 36K объектами, каждый объект имеет int, 2 строки,2 даты (все поля не пустые). Многие строки повторяются (все они принадлежат какому-то словарю с ~ 100 возможными значениями). Существует несколько сотен элементов для каждого значения int, даты и время более или менее случайны.
Этот клиент и вызываемая служба (и SQL) работают на одном компьютере. Поскольку я не могу изменить объекты, возвращаемые из службы, я не могу использовать управляемый атрибутами режим protobuf-net и вынужден использовать суррогатный подход.
Кроме того, клиент не ссылается ни на какие фактические типыиз службы B он работает с использованием сгенерированных WCF прокси (поэтому суррогаты protobuf сопоставляются с этими сгенерированными типами).
Я ожидал, что protobuf будет самым быстрым, затем tcp с бинарным кодером по умолчанию и затем медленный текстна основе http.
Фактическое время отличается (время - это среднее время, затраченное на один запрос в мс:
- Http - 442ms
- Protobuf - 445ms
- Tcp - 514ms
Точные числа немного отличаются каждый раз, но имеют одинаковый шаблон - Http и Protobuf более или менее одинаковы, Tcp медленнее на 10-15%.
Измерения были выполнены, когда и клиент, и сервис скомпилированы в режиме Release Любой ЦП и запущен из командной строки, на 64-битной Win10 с 16G Ram.
Время включает также процессЭто делается B, выборка данных из SQL и т. д., так что они сами по себе бессмысленны.
Итак, у кого-нибудь есть идеи, что я делаю не так, или почему Http внезапно стал самой быстрой лошадкой в стабильной версии? :)
В последний (и первый) раз, когда я прикасался к WCF, ~ 13 лет назад, ребята, которые написали код, также не были экспертами WCF, поэтому, возможно, я упускаю из виду нечто очевидное.