Перейти к основному содержимому
Версия: 4.x

Производительность и качество

Архитектурные решения, влияющие на пропускную способность​

  • Одна сериализация на рассылку. Рассылка сериализуется один раз, и одни и те же байты записываются каждому локальному получателю.
  • Параллельный fanout. Локальным получателям данные записываются параллельно, каждому с ограничением BroadcastSendTimeout, поэтому медленный сокет прерывается, не задерживая остальных.
  • Ограниченный объём работы на соединение. Одновременно выполняется не больше MaxConcurrentRequestsPerConnection запросов; дальнейшее чтение ждёт, поэтому один занятый клиент не может поставить в очередь неограниченный объём работы.
  • Последовательная запись. У каждого сокета одновременно только один писатель; фреймы ответов и рассылок никогда не перемешиваются.

Бенчмарки​

Микробенчмарки локального Release-прогона тега v4.0.0 на .NET 10.0.12, AMD Ryzen 7 3700X, Windows 11 (медиана пяти замеров, payload 364 байта). Транспорт — in-memory приёмник без сетевого I/O, поэтому эти числа показывают накладные расходы библиотеки, а не сквозную задержку.

СценарийПолучателиВремя на операциюПамять на операцию
Сериализация для каждого получателя1000.356 ms39.2 KB
Однократная сериализация1000.004 ms1.2 KB
In-memory fanout1000.210 ms36.3 KB
Сериализация для каждого получателя1 0003.693 ms385 KB
Однократная сериализация1 0000.010 ms1.2 KB
In-memory fanout1 0002.680 ms268 KB
Сериализация для каждого получателя10 0006.431 ms3.84 MB
Однократная сериализация10 0000.023 ms1.2 KB
In-memory fanout10 00013.656 ms2.65 MB
Разбор 1 000 запросов–2.349 ms984 KB
  • Сериализация для каждого получателя и однократная сериализация сравнивают наивную сериализацию под каждого клиента с общим payload в DarkWS.
  • In-memory fanout — это настоящая рассылка через IBroadcaster и in-memory backplane каждому получателю.
  • Разбор 1 000 запросов разбирает конверты запросов, около 2 µs на запрос.

В 5.0 локальная доставка переработана: тот же fanout на 1 000 получателей занимает там около 0.14 ms и 12 KB (см. документацию 5.x).

Результаты зависят от железа и среды выполнения; сравнивайте прогоны на одной и той же машине. Они не моделируют TLS, медленных клиентов и работу обработчиков.

Тесты​

Набор тестов 4.0.0 запускается на .NET 8, 9 и 10:

НаборТесты
Сервер (DarkWS)109
.NET-клиент и DI41
Redis backplane (настоящий Redis в Docker)14
Браузерный клиент (Vitest)41

Пороги покрытия проваливают сборку, если у любого пакета покрытие ниже 90% по строкам или 80% по ветвям. Покрытие в 4.0.0:

ПакетСтрокиВетви
DarkWS95.4%91.8%
DarkWS.Redis96.1%100%
DarkWS.Client98.4%91.7%
DarkWS.Client.DependencyInjection100%100%
darkws97.4%92.6%

Помимо модульных тестов, проверка тестирует Redis backplane с StackExchange.Redis 2.13.17 и 3.2.1, упаковывает каждый NuGet-пакет, проверяет его XML-документацию и символы, устанавливает в чистый проект-потребитель, запускает на всех целевых фреймворках и упаковывает npm-пакет из чистой копии, чтобы проверить его сборку.

Стабильность API​

Публичные API отслеживаются с помощью PublicApiAnalyzers: любое изменение публичной поверхности должно быть задекларировано и проверено, иначе сборка падает. Ломающие изменения выходят только в мажорных версиях, с инструкциями по миграции в changelog.