1

测试下载网页源代码的不同可能性我得到了以下结果(以毫秒为单位的平均时间到 google.com、9gag.com):

  • 普通 HttpWebRequest:169、360
  • Gzip HttpWebRequest:143、260
  • WebClient 获取流: 132、295
  • WebClient 下载字符串:143、389

因此,对于我的 9gag 客户端,我决定采用 gzip HttpWebRequest。问题是,在我的实际程序中实现后,请求花费了两倍以上的时间。
仅在两个请求之间添加 Thread.Sleep 时也会出现问题。

编辑:
只是稍微改进了代码,仍然是同样的问题:在循环中运行时,当我在请求之间添加延迟时,请求需要更长的时间

for(int i = 0; i < 100; i++)
{
    getWebsite("http://9gag.com/");
}

每个请求大约需要 250 毫秒。

for(int i = 0; i < 100; i++)
{
    getWebsite("http://9gag.com/");
    Thread.Sleep(1000);
}

每个请求大约需要 610 毫秒。

    private string getWebsite(string Url)
    {
        Stopwatch stopwatch = Stopwatch.StartNew();

        HttpWebRequest http = (HttpWebRequest)WebRequest.Create(Url);
        http.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        string html = string.Empty;

        using (HttpWebResponse webResponse = (HttpWebResponse)http.GetResponse())
        using (Stream responseStream = webResponse.GetResponseStream())
        using (StreamReader reader = new StreamReader(responseStream))
        {

            html = reader.ReadToEnd();
        }

        Debug.WriteLine(stopwatch.ElapsedMilliseconds);
        return html;
    }

有什么想法可以解决这个问题吗?

4

2 回答 2

5

也许试一试,尽管它可能只会帮助您处理单个请求,并且在执行多线程版本时实际上会使事情变得更糟。

ServicePointManager.UseNagleAlgorithm = false;

这是 MSDN 文档对HttpWebRequest 类的引用

另一个可能影响性能的选项是使用 UseNagleAlgorithm 属性。当此属性设置为 true 时,TCP/IP 将尝试对 HTTP 连接使用 TCP Nagle 算法。Nagle 算法在发送 TCP 数据包时聚合数据。在通过网络发送数据之前,它将小消息序列累积成较大的 TCP 数据包。使用 Nagle 算法可以优化网络资源的使用,尽管在某些情况下性能也会降低。通常对于恒定的大容量吞吐量,使用 Nagle 算法实现性能改进。但是对于较小吞吐量的应用程序,可能会看到性能下降。

应用程序通常不需要更改设置为 true 的 UseNagleAlgorithm 属性的默认值。但是,如果应用程序正在使用低延迟连接,则将此属性设置为 false 可能会有所帮助。

于 2012-07-07T23:07:47.320 回答
1

我认为您可能会泄漏资源,因为您没有在每个方法调用中处理所有 IDisposable 对象。

给出这个版本并尝试看看它是否给你一个更一致的执行时间。

public string getWebsite( string Url )
  {
     Stopwatch stopwatch = Stopwatch.StartNew();

     HttpWebRequest http = (HttpWebRequest) WebRequest.Create( Url );
     http.Headers.Add( HttpRequestHeader.AcceptEncoding, "gzip,deflate" );

     string html = string.Empty;
     using ( HttpWebResponse webResponse = (HttpWebResponse) http.GetResponse() )
     {
        using ( Stream responseStream = webResponse.GetResponseStream() )
        {
           Stream decompressedStream = null;

           if ( webResponse.ContentEncoding.ToLower().Contains( "gzip" ) )
              decompressedStream = new GZipStream( responseStream, CompressionMode.Decompress );
           else if ( webResponse.ContentEncoding.ToLower().Contains( "deflate" ) )
              decompressedStream = new DeflateStream( responseStream, CompressionMode.Decompress );

           if ( decompressedStream != null )
           {
              using ( StreamReader reader = new StreamReader( decompressedStream, Encoding.Default ) )
              {
                 html = reader.ReadToEnd();
              }

              decompressedStream.Dispose();
           }
        }
     }

     Debug.WriteLine( stopwatch.ElapsedMilliseconds );

     return html;
  }
于 2012-07-06T12:35:39.447 回答