4

次のことを行うコンソールアプリケーションがあります。

  1. 入力ファイルを読み取ります。入力ファイルには、数千行に及ぶ行単位のデータが含まれています
  2. 入力ファイルを前処理し、中間ファイルに変換します。中間ファイルの行数は同じです。
  3. 中間ファイルから一度に 1 行を読み取り、Web 要求を作成して Web サーバーに送信します。
  4. リクエストごとに Web サーバーからのレスポンスを一度に読み取り、処理 (解析) して出力ファイルに書き込みます。出力には、入力ファイルと同じ数の行も含まれます。

現在、アプリケーションは正常に動作していますが、非常に遅いです。アプリケーションのパフォーマンスを改善して、少し速くしたいと考えています。

  1. この場合に使用できるさまざまなアプローチについて誰か教えてもらえますか?

  2. マルチスレッドが問題の解決策である場合、誰かがいくつかの開始点を提案できますか?

編集:すべてのリクエストは同じサーバーに送られます。サーバーに関する限り、私はその許容範囲についてほとんど、またはまったく知りません (これに到達する場合は、サーバーへの要求スレッドの数を制限することを検討するかもしれません)。

4

3 に答える 3

2

糸を通すか、糸を使わないか?それが質問です...

質問のマルチスレッド部分に対する単純で正しい答えは次のとおりです。はい、1) アルゴリズムに従って実現可能であり、2) I/O バウンド ops を含むか、CPU バウンド ops に複数のコアがある場合、すぐに

最初のポイント: 実現可能性

  1. ステップ 2 を実行するには、ステップ 1 を完了する必要があります。マルチスレッドはまだありません
  2. ステップ 3 では、ステップ 2 を完了する必要がありますが、独立した行ごとのアクティビティ (行ごとに 1 つの要求)が含まれます。ビンゴ!!
  3. ステップ 4 では、ステップ 3 ですべての要求を完了する必要があります。マルチスレッドはそこで終了します。

2点目:操作の種類

Web リクエストは I/O バウンド操作です。最大の利益を得ることができます。フォールトトレラントかどうかに関係なく、同じサーバーに対してリクエストを実行しているため、クエリレートを制限する必要があります。同時リクエストの数を適切に調整する必要がありますが、コードで定数を使用する場合 ( などconst int NUMBER_OF_THREADS = 4;) は、適切な出発点になります。

提案

セマフォを使用して同時要求を処理します。

前に行ったように、ファイルを読み取り、中間ファイルに変換してプログラムを開始します。

終了したら、固定サイズの配列を作成し(最終ファイルには同じ数の行があるため、割り当てることができると述べました)、各行のループを開始します。

  1. 定数で初期化されるセマフォを取得しますNUMBER_OF_THREADS。これにより、メイン スレッドは 4 つの同時スレッドをアクティブにできます。
  2. 行、ターゲット配列、およびインデックスを渡してスレッドを開始します (リストがクラス メンバーである場合、実際にはそれらすべてをパラメーターとして渡す必要はありません)。

ループの後、AutoResetEvent簡単に説明するのを待ちます

スレッドで、次の操作を行います。

  1. Web リクエストを実行する
  2. 処理結果
  3. 結果を対応するターゲット配列行に保存します
  4. メソッドを使用して、スレッド間で共有される変数(ここでは説明しません) をインクリメントします。Interlocked.Increment()
  5. if共有変数equals行数、私が言及したものをthen解放すると、AutoResetEventメインスレッドのロックが解除されます

チューニング

4 つの同時スレッドから始めます。それらを 8 に増やして、パフォーマンスを確認してください。12 スレッドを超えないようにすることをお勧めしますが、ここにいる他の人は、それは多すぎるかもしれないと言うかもしれません... それは試行錯誤です。

于 2013-01-23T08:49:45.450 に答える
0

内部メッセージキューと生産者/消費者チェーンに基づいてアプリケーションを作成します。

* -> * -> * -> *

ここで、それぞれ*が実行しているスレッドです:読み取り、処理、WSのクエリ、後処理。*ノードは、生成キューがいっぱいになるか、消費キューが空になるとスリープ状態になります。

必要に応じて、次のように、各ポイントで(おそらくWSハンドラーで)複数のコンシューマーを作成できます。

         / * \ 
* -> * ->  *  -> *
         \ * /

アーキテクチャの準備ができたら、各ポイントでキューのサイズを変更することでアプリを微調整できます。

さらに、スレッドプールを使用して各処理ノードを処理できるため、プロセッサを最大限に活用することができます。

于 2013-01-23T08:44:23.267 に答える
0

ファイルを読みながら、ファイルを書き込んでいます。最初に頭に浮かぶのは、ファイルを大きなブロック (BufferedReader) で読み取って、ディスクがシークしすぎないようにすることです。

サーバーに関しては、私の経験では、ほとんどの Web サーバーは 1 秒あたりの複数のリクエストに対して非常に寛容です。サーバーを自分でホストしている場合は、非同期 Web 要求を使用して何が起こるかを理解するだけです...ただし、その音から、単純な Web クローラーを作成していることになります。この場合、辛抱強く待つことを強くお勧めします。他人のサーバーは決して良い考えではありません。目安として、当社の Web クローラーは常に、サーバーごとに 1 秒あたり 1 リクエストに制限されていました。

于 2013-01-23T08:38:08.597 に答える