РЕДАКТИРОВАТЬ: добавлены образцы воспроизведения + Я запускаю это (на всех серверах) на Ubuntu 18.04 с .Net Core 2.2.203.
РЕДАКТИРОВАТЬ: протестировано из дома с моего ноутбука с Windows 10; те же результаты
У меня есть кусок очень простого кода для HttpClient (статический, как рекомендовано, но я также тестировал с использованием ()):
sw.Start(); // stopwatch
client.GetAsync(url).Result();
sw.Stop();
и затем для скручивания:
time curl -L "url" > /dev/null
и для рыси:
time lynx "url" > /dev/null
Разница ошеломляет; это действительно зависит от запрошенного сервера / URL, но я получаю различия в 2-50 раз медленнее от HttpClient, чем curl / lynx для запросов от того же сервера .
Я перепробовал все найденные исправления;
HttpHandler без прокси (UseProxy = false, Proxy = null)
Использование await вместо .Result (не то, что должно иметь значение, и это действительно не так)
WebClient
ModernHttpClient
и упаковщик Curl CurlThin
Последний вариант (очевидно) дал правильные результаты, остальные (параметры .NET) просто невероятно медленные.
Сейчас я использую обертки Curl, потому что результаты .NET просто неверны и замедляют работу нашего стека.
Кто-нибудь имел это раньше? Я попробовал (как вы можете видеть выше) все «исправления», предоставленные Googling, но ни одна из них не предоставила никакой помощи.
РЕДАКТИРОВАТЬ: от Мэтти в комментариях, если вы используете Windows с Powershell, это тоже воспроизводит;
(Measure-Command -Expression { $site = Invoke-WebRequest -Uri "reddit.com" }).Milliseconds
РЕДАКТИРОВАТЬ: Код для воспроизведения:
использовать с:
dotnet run -- https://reddit.com
using System;
using System.Diagnostics;
using System.Net.Http;
namespace Download.Playground
{
class Program
{
static HttpClient client;
static void Main(string[] args)
{
HttpClientHandler hch = new HttpClientHandler();
hch.Proxy = null;
hch.UseProxy = false;
client = new HttpClient(hch);
Stopwatch sw = new Stopwatch();
sw.Start();
var result = client.GetAsync(args[0]).Result;
sw.Stop();
Console.WriteLine($"Spent {sw.ElapsedMilliseconds}ms");
}
}
}
Маленький скрипт для проверки 20 раз, запустите с:
./runbench https://reddit.com
#!/bin/bash
for i in {1..20}
do
dotnet run -- $1
time curl -L $1 > /dev/null
done