Здравствуйте, Codealot, Вы писали:
C>Получается около 40-50 запросов в секунду. И хотя я не ожидал миллионов, но это — вообще курам на смех. C>Я что-то упускаю?
Если влоб — используй при каждом запросе свой HttpClient (вместе с хэндлером) (не забывая вызывать Dispose), можно создать пул HttClient'ов размером с MaxDegreeOfParallelism, и при каждом запросе юзать свой HttClient.
Когда юзаешь при многопотоке один HttpClient для всех запросов (что типа рекомендуется во всём инете), наблюдается что внутри явно есть какие-то блокировки при запросе к одному адресу, что вырождается чуть ли не в последовательное выполнение запросов.
Здравствуйте, Codealot, Вы писали:
C>Получается около 40-50 запросов в секунду. И хотя я не ожидал миллионов, но это — вообще курам на смех. C>Я что-то упускаю?
А сервер не может тормозить? Вдруг это всё в него упирается?
Я бы порекомендовал инструментировать код и записать статистику распределения количества запросов по времени выполнения.
Плюс записать на сервере сколько реально выполняется параллельных запросов. Это может дать информацию для дальнейшего поиска.
Здравствуйте, bnk, Вы писали:
bnk>Какой здесь вообще смысл в SetMaxThreads?
Если бы использовался ThreadPool.SetMinThreads, то это повлияло бы на увеличение потоков в пуле без задержек до указанного предела, дальнейшее увеличение будет идти с задержками.
Здравствуйте, Codealot, Вы писали:
bnk>>У тебя на компе 4000 ядер что ли?
C>Сеть не в ядра упирается. Ты что, реально думаешь, что один тред — одно ядро?
Я не специалист по многопоточности, просто наивный вопрос — какой смысл разрешать 4000 потоков если реально выполнятся будет столько, сколько поддерживает проц?
На 4000 потоков же памяти уйдет прорва (на стек для каждого по мегабайту?) Плюс на переключение расходы?
bnk>>Какой здесь вообще смысл в SetMaxThreads?
C>На всякий случай, чтобы хватило с гарантией.
Можно ссылку, чтобы понять почему это лучше, чем 16 (ну или сколько у тебя ядер?)
Здравствуйте, bnk, Вы писали:
bnk>Я не специалист по многопоточности, просто наивный вопрос — какой смысл разрешать 4000 потоков если реально выполнятся будет столько, сколько поддерживает проц?
Потому что в данном случае они упираются во ввод-вывод, а не в процессор.
bnk>На 4000 потоков же памяти уйдет прорва (на стек для каждого по мегабайту?)
Всего лишь. Не цена, если нужна скорость. Но здесь это просто для уверенности, что проблема не в этом.
Здравствуйте, Codealot, Вы писали:
C>Я что-то упускаю?
А ты что хочешь проверить?
Сделай просто цикл, без всяких parallel, чтобы посчитать время запроса-ответа. Если сравнишь с таймингом сервера, то получишь чистые накладные расходы httpclient.
Сделай пачку GetAsysnc, а потом сразу все Task.WhenAll, чтобы узнать при каком количестве одновременных запросов сервер начинает проседать.
Здравствуйте, Codealot, Вы писали:
C>Всего лишь. Не цена, если нужна скорость. Но здесь это просто для уверенности, что проблема не в этом.
Я не понимаю как создание 4000 потоков на процессоре который поддерживает 16 (для примера), может в принципе что-то ускорить?
Мне кажется что ты только замедлишь этим? Ты пробовал убрать эту строчку и измерить время без нее?
Здравствуйте, bnk, Вы писали:
bnk> Я не понимаю как создание 4000 потоков на процессоре который поддерживает 16 (для примера), может в принципе что-то ускорить?
Элементарно! Пока все 16 потоков висят ожидая сеть, другие занимаются полезным делом. Потом следующие 16 и так далее. Наращивать потоки можно до исчерпания полосы пропускания. После, влияния на скорость уже не будет. Вообще, это глупая мантра, что число потоков должно быть равно числу ядер/потоков исполнения процессора. Все зависит от того чем эти потоки занимаются.
Здравствуйте, rudzuk, Вы писали:
bnk>> Я не понимаю как создание 4000 потоков на процессоре который поддерживает 16 (для примера), может в принципе что-то ускорить?
R>Элементарно! Пока все 16 потоков висят ожидая сеть, другие занимаются полезным делом. Потом следующие 16 и так далее. Наращивать потоки можно до исчерпания полосы пропускания. После, влияния на скорость уже не будет. Вообще, это глупая мантра, что число потоков должно быть равно числу ядер/потоков исполнения процессора. Все зависит от того чем эти потоки занимаются.
Там же Async/Await (Parallel.ForEachAsync)?! Никто там не "висеть ожидая сеть" не должен. NODEJS вообще "однопоточная" например?
Здравствуйте, bnk, Вы писали:
bnk> Там же Async/Await (Parallel.ForEachAsync)?! Никто там не "висеть ожидая сеть" не должен. NODEJS вообще "однопоточная" например?
Здравствуйте, rudzuk, Вы писали:
R>Здравствуйте, bnk, Вы писали:
bnk>> Я не понимаю как создание 4000 потоков на процессоре который поддерживает 16 (для примера), может в принципе что-то ускорить?
R>Элементарно! Пока все 16 потоков висят ожидая сеть, другие занимаются полезным делом. Потом следующие 16 и так далее. Наращивать потоки можно до исчерпания полосы пропускания. После, влияния на скорость уже не будет. Вообще, это глупая мантра, что число потоков должно быть равно числу ядер/потоков исполнения процессора. Все зависит от того чем эти потоки занимаются.
При async/await потоки не ожидают сеть. Они выполняются только при отправке запроса и получении ответа. За этим следит посредством портов ввода/вывода. https://habr.com/ru/articles/470830/
Здравствуйте, bnk, Вы писали:
bnk>Там же Async/Await (Parallel.ForEachAsync)?! Никто там не "висеть ожидая сеть" не должен. NODEJS вообще "однопоточная" например?
bnk>Я не понимаю как создание 4000 потоков на процессоре который поддерживает 16 (для примера), может в принципе что-то ускорить?
Что ты слышал про зеленые потоки?
Здравствуйте, Gt_, Вы писали:
bnk>>Я не понимаю как создание 4000 потоков на процессоре который поддерживает 16 (для примера), может в принципе что-то ускорить?
Gt_>Что ты слышал про зеленые потоки?
Ничего практически (в контексте .net по крайней мере).
То есть, вообще я термин такой слышал, но что он означает я не совсем в курсе.
Насколько я понял это типа эмуляция потоков? Типа недоделанный async/await, или?
bnk>>>Я не понимаю как создание 4000 потоков на процессоре который поддерживает 16 (для примера), может в принципе что-то ускорить?
Gt_>>Что ты слышал про зеленые потоки?
bnk>Ничего практически (в контексте .net по крайней мере). bnk>То есть, вообще я термин такой слышал, но что он означает я не совсем в курсе. bnk>Насколько я понял это типа эмуляция потоков? Типа недоделанный async/await, или?
это async/await недоделанный зеленый поток, а зеленый поток это полностью автоматизированный async/await без засирания языка не нужными конструкциями. так вот, с зелеными потоками простенький сервак с рест сервисом способен чуть ли не миллион запросов в секунду держать, что на несколько больше процессорных threads.
вся фишка в том, что пока одни потоки ждут и/о другие могут утилизировать cpu.
Здравствуйте, Codealot, Вы писали:
C>Получается около 40-50 запросов в секунду. И хотя я не ожидал миллионов, но это — вообще курам на смех. C>Я что-то упускаю?
Да, упускаешь. Этот код показывает не быстродействие HttpClient, а сколько можно запросов выполнить в синхронном режиме с настроенной параллелизацией. HttpClient может легко держать тысячи реквестов в секунду
Здравствуйте, Codealot, Вы писали:
C>Странно, но это как-то связано с компьютером. Запускаю на одном, и получаю жалкие крохи. Запускаю на другом, и влегкую 3-4 тысячи.
firewall? Антивирус?
C>Странно, но это как-то связано с компьютером. Запускаю на одном, и получаю жалкие крохи. Запускаю на другом, и влегкую 3-4 тысячи.
Это связано с тем, что
using var response = await httpClient.GetAsync(url, token);
делает следующее:
1. (в первый раз) устанавливает сооединение (DNS, etc.)
2. [HttpClient] Посылает сообщение
3. Сообщение пересылается по сети
4. Сервер обрабатывает сообщение
5. Ответ пересылается по сети
6. [HttpClient] Ответ обрабытывается HttpClient
Здесь HttpClient почти ничего не делает по сравнению с другими пунктами
Здравствуйте, Codealot, Вы писали:
C>Здравствуйте, vmpire, Вы писали:
V>>firewall? Антивирус?
C>Одинаково — Defender. Разница в том, что где тормозит — винда 11, а где нет — 10. Но это вряд ли объясняет проблему.
Маршрут везде одинаковый? пинги?
Здравствуйте, Codealot, Вы писали:
V>>firewall? Антивирус?
C>Одинаково — Defender. Разница в том, что где тормозит — винда 11, а где нет — 10. Но это вряд ли объясняет проблему.
Можно на сервере посмотреть очередь запросов. Скорее всего ServicePointManager.DefaultConnectionLimit не работает
ServicePointManager.DefaultConnectionLimit = 4;
или
Uri uri = new Uri("http://www.contoso.com/");
ServicePoint sp = ServicePointManager.FindServicePoint(uri);
sp.ConnectionLimit = newLimit;
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Codealot, Вы писали:
S>> Так ServicePointManager это про клиента
C>Не, на клиенте уже пробовал. Однофигственно.
Интересно, а что выдает
var url = "https://localhost:7065/weatherforecast";
Uri uri = new Uri(url);
ServicePoint sp = ServicePointManager.FindServicePoint(uri);
sp.ConnectionLimit??
Там явно проблема с количеством соединений с сервером
и солнце б утром не вставало, когда бы не было меня
Поковырявишсь выяснил, что скорость радикально меняется в зависимости от того, запускается прога под отладчиком или без. И без него, скорость на "медленном" компе уже намного лучше.
Но хотел бы я знать, почему это так сильно влияет на один комп, но не на другой.