@ambulatur

C# Scraper fast as hell, tasks or threads?

Доброго времени суток, имеется собственный веб сервер соединённый с бд, а так же клиент к нему.
Результаты с веб-сервера получаю посредсвом Get запроса.
С клиента отправляется запрос используя код ниже:
public void GetInfo()
        {
while(true)
{
            using (var request = new HttpRequest()) // Leaf.xNet as analog HttpClient
            {
                try
                {
                    var response = request.Get("https://site.org/show").ToString();
                    Console.WriteLine($"{response}");
                }
                catch (Exception ex)
                {
                    ex = null;
                }
            }
}
        }

А затем вызывается как :
int maxThreads = 200;
for(int i = 0; i<maxThreads,i++)
{
new Thread(()=>GetInfo()).Start();
}

И в результате в "консоль" получаю данные вида "request number # info XXXX".
Вопрос состоит из того, как всё это дело максимально ускорить? Не считая то что нужно использовать ihttpclientfactory из за трудоёмкости создания http client'a (xNet под катом использует httpclientfactory).
Использовать таски - не вариант, если к request.Get("https://site.org/show").ToString(); добавить await Task.Run(()=>{x}); это будет правильнее, но скорость получения данных с сервера резко упадёт, на практическом опыте, создание новых потоков которые внутри выполняют запросы - быстрее чем async, быстрее чем при использовании ThreadPool.
  • Вопрос задан
  • 203 просмотра
Решения вопроса 1
vabka
@vabka Куратор тега .NET
Токсичный шарпист
Если хотите что-то ускорить - ускоряйте CPU-bound штуки и уменьшайте количество аллокаций (в идеале до 0).
> try-catch
постарайтесь обойтись без исключений. Лично я знаю пока только 1 высокоуровневый HTTP клиент, который работает без них - ClusterClient, но я не уверен, умеет ли он в прокси, если вы их используете.
> быстрее чем при использовании ThreadPool
Если у вас так много запросов, то вы быстро упрётесь в лимит потоков в ОС :)
Лучше увеличьте размер тредпула на старте.

Ещё попробуйте уйти с .NET Framework на .NET 5 - сразу почти бесплатно получите ускорение, если используется System.Net.HttpClient (там целая куча низкоуровневых оптимизаций по памяти сделано)

ЗЫ: сам я ничего не знаю про xNet, что там в недрах используется, но судя по тому, что там в репозитории уже 5 лет нет обновлений - врядли там используются современные вещи.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
А есть какие-нибудь примерные цифры "на сколько это надо ускорить"? "Максимально" - это слишком абстрактная метрика, чтобы с ней работать.
Проблемы со скоростью на стороне клиента? Сервер достаточно быстро отвечает на запросы на своей стороне? Несколько сомнительно, чтобы инициализация http-клиента была самым критичным bottleneck'ом операции.
Какая цель в целом? Получить какие-то данные с веб сервера в реальном времени? Много ли этих данных? Если нет, но надо максимально ускорить их получение - можно посмотреть в сторону альтернативных сетевых протоколов (например использовать очереди, см.RMQ).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы