РЕДАКТИРОВАТЬ: добавлены образцы воспроизведения + Я запускаю это (на всех серверах) на 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