Мой вопрос - разрешить аргумент с моими сотрудниками на С++ vs С#.
Мы реализовали сервер, который получает большое количество потоков UDP. Этот сервер был разработан на С++, используя асинхронные сокеты и перекрывающиеся ввода-вывода с использованием портов завершения. Мы используем 5 портов завершения с 5 потоками. Этот сервер может легко обрабатывать пропускную способность 500 Мбит/с в гигабитной сети без потери пакетов/ошибок (мы не проталкивали наши тесты дальше 500 Мбит/с).
Мы попытались повторно реализовать тот же тип сервера на С#, и нам не удалось достичь той же входящей пропускной способности. Мы используем асинхронный прием с использованием метода ReceiveAsync
и пула SocketAsyncEventArgs
, чтобы избежать накладных расходов на создание нового объекта для каждого приема. Каждый SAEventArgs
имеет буфер, установленный для него, поэтому нам не нужно выделять память для каждого приема. Бассейн очень, очень большой, поэтому мы можем поставить в очередь более 100 запросов на получение. Этот сервер не способен обрабатывать входящую пропускную способность более 240 Мбит/с. По этому ограничению мы теряем некоторые пакеты в наших UDP-потоках.
Мой вопрос в следующем: следует ли ожидать такой же производительности с использованием сокетов С++ и сокетов С#? Мое мнение таково, что он должен быть такой же, если в .NET правильно управлять памятью.
Боковой вопрос: кто-нибудь знает хорошую статью/ссылку, объясняющую, как сокеты .NET используют порты завершения ввода/вывода под капотом?