如何获得快速的.Net Http请求

Mar*_*phy 10 .net c# http httpwebrequest libcurl

我需要一个Http请求,我可以在.Net中使用,这需要不到100毫秒.我能够在浏览器中实现这一点,所以我真的不明白为什么这在代码中是个问题.

我已经尝试过WinHTTP以及WebRequest.Create,它们都超过500毫秒,这对我的用例来说是不可接受的.

以下是我试图通过的简单测试的示例.(WinHttpFetcher是我写的一个简单的包装器,但是它确实是一个获取请求的最简单的例子,我不确定它是否值得粘贴.)

我正在使用LibCurlNet获得可接受的结果,但如果同时使用该类,我会收到访问冲突.此外,由于它不是托管代码,必须复制到bin目录,因此使用我的开源项目进行部署并不理想.

尝试另一个实现的任何想法?

    [Test]
    public void WinHttp_Should_Get_Html_Quickly()
    {
        var fetcher = new WinHttpFetcher();
        var startTime = DateTime.Now;          
        var result = fetcher.Fetch(new Uri("http://localhost"));
        var endTime = DateTime.Now;
        Assert.Less((endTime - startTime).TotalMilliseconds, 100);
    }
    [Test]
    public void WebRequest_Should_Get_Html_Quickly()
    {
        var startTime = DateTime.Now;
        var req = (HttpWebRequest) WebRequest.Create("http://localhost");
        var response = req.GetResponse();
        var endTime = DateTime.Now;
        Assert.Less((endTime - startTime).TotalMilliseconds, 100);
    }
Run Code Online (Sandbox Code Playgroud)

Tim*_*oyd 16

在进行基准测试时,最好至少丢弃前两个时间,因为它们可能会扭曲结果:

  • 时序1:由JIT开销支配,即将字节代码转换为本机代码的过程.
  • 时序2:JIT代码的可能优化传递.

此后的计时将更好地反映重复表现.

以下是测试工具的示例,该测试工具将自动忽略JIT和优化传递,并在获取平均值以确定性能之前运行测试一定数量的迭代.正如您所看到的那样,JIT传递需要花费大量时间.

JIT:410.79ms

优化:0.98ms.

平均超过10次迭代:0.38ms

码:

[Test]
public void WebRequest_Should_Get_Html_Quickly()
{
    private const int TestIterations = 10;
    private const int MaxMilliseconds = 100;

    Action test = () =>
    {
       WebRequest.Create("http://localhost/iisstart.htm").GetResponse();
    };

    AssertTimedTest(TestIterations, MaxMilliseconds, test);
}

private static void AssertTimedTest(int iterations, int maxMs, Action test)
{
    double jit = Execute(test); //disregard jit pass
    Console.WriteLine("JIT:{0:F2}ms.", jit);

    double optimize = Execute(test); //disregard optimize pass
    Console.WriteLine("Optimize:{0:F2}ms.", optimize);

    double totalElapsed = 0;
    for (int i = 0; i < iterations; i++) totalElapsed += Execute(test);

    double averageMs = (totalElapsed / iterations);
    Console.WriteLine("Average:{0:F2}ms.", averageMs);
    Assert.Less(averageMs, maxMs, "Average elapsed test time.");
}

private static double Execute(Action action)
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    action();
    return stopwatch.Elapsed.TotalMilliseconds;
}
Run Code Online (Sandbox Code Playgroud)