EDIT: added reproduction samples + I am running this (on all servers) on Ubuntu 18.04 with .Net Core 2.2.203.
EDIT: tested from home from my Windows 10 laptop; same results
I have a piece of very simple code for HttpClient (static as recommended, but I tested with using() as well):
sw.Start(); // stopwatch
client.GetAsync(url).Result();
sw.Stop();
and then for curl:
time curl -L "url" > /dev/null
and for lynx:
time lynx "url" > /dev/null
The difference is staggering; it really depends on the requested server/url, but i'm getting differences to 2-50x slower from HttpClient than curl/lynx on requests from the same server.
I tried all fixes I could find;
HttpHandler without proxy (UseProxy = false, Proxy = null)
Using await instead of .Result (not that that should make a difference and it indeed does not)
WebClient
ModernHttpClient
and the Curl wrapper CurlThin
That last option (obviously) did give the right results, the rest (.NET options) are just incredibly slow.
For now i'm using the Curl wrappers because the .NET results are just incorrect and slowing our stack down.
Did anyone have this before? I tried (as you can see above) all 'fixes' provided by Googling, but none of them provided any help.
EDIT: from Matthiee in the comments, if you are running Windows with Powershell, this reproduces it too;
(Measure-Command -Expression { $site = Invoke-WebRequest -Uri "reddit.com" }).Milliseconds
EDIT: Code to reproduce:
use with:
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");
}
}
}
Little script to check 20 times, run with:
./runbench https://reddit.com
#!/bin/bash
for i in {1..20}
do
dotnet run -- $1
time curl -L $1 > /dev/null
done