Производительность сериализации basicHttpBinding, netTcpBinding, расширение protobuff - PullRequest
2 голосов
/ 13 октября 2019

Я наблюдаю странные проблемы с производительностью - из трех способов доступа к службе 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, поэтому, возможно, я упускаю из виду нечто очевидное.

...