2009-05-23 82 views
19

私は、HttpWebResponse.GetResponse()とStreamreader.ReadToEnd()を使用して、StreamReader.Read()を使用して試して、 をC#で制限されたWebクローラーを実装しようとしています。私のHTML文字列を構築するためのループ。HTTPWebResponse + StreamReader非常に遅い

私は約5-10Kのページしかダウンロードしていません。

非常に遅いです!たとえば、平均GetResponse()時間は約0.5秒ですが、平均StreamReader.ReadToEnd()時間は約5秒です!

すべてのサイトは、自分の場所に非常に近いため、高速である必要があります。 (エクスプローラではD/Lにほとんど何もかかりません)、私はプロキシを使用していません。

My Crawlerには、同じサイトから同時に約20のスレッドが読み込まれています。これは問題を引き起こす可能性がありますか?

どのようにしてStreamReader.ReadToEnd回を減らすことができますか?

答えて

8

WebClientのDownloadStringは、HttpWebRequestの単純なラッパーです。一時的に使用して、速度が向上するかどうか確認できますか?状況がずっと速くなったら、コードを共有して、何が間違っているかを調べることができますか?

EDIT:

それは、HttpWebRequestのは、IEの '最大同時接続' 設定を観察するようで、同じドメインにこれ​​らのURLですか?あなたはそれが役立つかどうかを見るために接続制限を増やすことができますか?私はこの問題についてthis articleが見つかりました:

デフォルトでは、あなたは2-3より 以上を実行することはできません非同期のHttpWebRequest(OSに に依存します)。

<system.net> 
    <connectionManagement> 
    <add address="*" maxconnection="65000" /> 
    </connectionManagement> 
</system.net> 
+0

Webクライアントを使用してみましたが、同じ結果(平均時間は変更されていません)。 私は180MBPSの平均d/lスピードで1.5MBPSの接続があることを言及する必要があります 私はStreamReader.Readを同時に呼び出すすべてのスレッドがそれと関連があるかもしれないと考えていましたか?それともこれは無関係ですか? – Roey

+0

私の経験上、このような接続では、帯域幅を3-4スレッドで飽和させます。あなたがpingをしているウェブサイトが本当に遅く、I/Oを待つスレッドがたくさんある場合を除き、もっと多くを実行する必要はありません。 – kgriffs

+1

うわー!!!私は非同期のHttpWebRequestを使用してクライアントあたり約300スレッドのテストサーバーをロードし、各スレッドは「シリアルに」ダウンロードしていました。 maxconnection設定を変更すると、各スレッドはデータを10倍高速にダウンロードできました。 –

15

HttpWebRequestのは、あなたのproxy settingsを検出するための時間がかかっすることができる。 (最も簡単な方法、私見)それを上書きするために、アプリケーションのconfig ファイルに セクションの下にこれを追加すること を忘れないでください。アプリケーションの設定にこれを追加してみてください:

<system.net> 
    <defaultProxy enabled="false"> 
    <proxy/> 
    <bypasslist/> 
    <module/> 
    </defaultProxy> 
</system.net> 

また、あなたをバッファからわずかなパフォーマンスの向上は、基礎となるオペレーティング・システムのソケットに行われたコールの数を減らすために読み込み表示される場合があります。

using (BufferedStream buffer = new BufferedStream(stream)) 
{ 
    using (StreamReader reader = new StreamReader(buffer)) 
    { 
    pageContent = reader.ReadToEnd(); 
    } 
} 
+0

ありがとうございます!それは数秒から数ミリ秒まで私のコードを完全にスピードアップしました! –

+0

C++の同等のコードは何ですか? using(...)はC++では動作しません – Edge

1

はあなたを持っていますServicePointManager.maxConnectionsを試しましたか?私は通常これに似たものを200に設定します。

1

私は問題は同じでしたが、最悪でした。 レスポンス=(HttpWebResponse)webRequest.GetResponse();私のコードでは は約10秒遅れてからコードを実行し、その後はダウンロードが飽和してしまいました。

クルトの答えdefaultProxyが有効= "false" を

は、問題を解決しました。今すぐ応答が即座にあり、接続の最大速度でhttpファイルをダウンロードすることができます:) 申し訳ありませんが悪い英語

1

私はApplication Configメソッドが動作しませんでしたが、問題は依然としてプロキシ設定のためでした。 30秒まで取るために使用私の単純な要求は、今では1

public string GetWebData() 
{ 
      string DestAddr = "http://mydestination.com"; 
      System.Net.WebClient myWebClient = new System.Net.WebClient(); 
      WebProxy myProxy = new WebProxy(); 
      myProxy.IsBypassed(new Uri(DestAddr)); 
      myWebClient.Proxy = myProxy; 
      return myWebClient.DownloadString(DestAddr); 
} 
4

を取り、私は同じ問題を抱えていたが、私はnullには、HttpWebRequestのプロキシパラメータが座っていたとき、それは問題を解決しました。

UriBuilder ub = new UriBuilder(url); 
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ub.Uri); 
request.Proxy = null; 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
+0

すばらしい解決策!私のために働く。 –

0

回答ありがとうございました。彼らは正しい方向に掘り下げてくれました。私のニーズに適合していない(私は解決策は、Webアプリケーションのためのものであることを理解されるような)アプリケーションの設定ファイルを変更するためのソリューションを提案しても、私は、同じパフォーマンスの問題に直面してきた、私の解決策を以下に示します。

HttpWebRequest webRequest; 

webRequest = (HttpWebRequest)System.Net.WebRequest.Create(fullUrl); 
webRequest.Method = WebRequestMethods.Http.Post; 

if (useDefaultProxy) 
{ 
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy; 
    webRequest.Credentials = CredentialCache.DefaultCredentials; 
} 
else 
{ 
    System.Net.WebRequest.DefaultWebProxy = null; 
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy; 
} 
0

なぜマルチスレッドでこの問題を解決できないでしょうか?マルチスレッド化はネットワーク待ち時間を最小限に抑え、バッファの内容をシステムメモリ(RAM)に格納するので、ファイルシステムを扱うことによるIOのボトルネックはありません。したがって、ダウンロードと解析に82秒かかる82ページは、15秒(4倍のプロセッサを想定)のようになります。私が何かを欠けているなら私を訂正してください。

____ダウンロードTHREAD _____ *

ダウンロードコンテンツ

フォームストリーム

読む内容

_________________________ *

+0

OPには、すでに「約20」のスレッドが使用されていることが記載されています。 – Spooky