しばらくの間、私を悩ませてきたパフォーマンスの最適化の問題があります。私はそれからより多くのパフォーマンスを絞り出そうとしましたが、あまり成功しませんでした.
システム(簡略化)は次のとおりです。
1) リクエストは HTTP Post 経由で受信されます (同期/インラインで応答する必要があります)
2) リクエストを処理し、レスポンスを返す (すべて XML)
3) 15 秒以内に結果の準備ができていない場合は、「サーバーがビジーです。後で試してください」タイプのメッセージで応答します。
中央のメッセージ処理メカニズムとして、メッセージをキューに入れ、開始し、待機するタスクベースのアプローチを使用しました (最大 15 秒)。
メッセージがほぼ瞬時に処理される場合、スループット (1 秒あたりの要求数) は非常に良好です (1000/秒)。ただし、メッセージ処理が 200 ミリ秒遅れると、これはかなりひどく 40/s に低下します。
いくつかのスニペット:
public void AddMessage() { Task.Factory.StartNew(() => { worker.ProcessMessage(); を返します。 }; } public MessageResponse GetResult() { task.Task.Wait(15 * 1000); スイッチ (タスク.ステータス) { ケース TaskStatus.Running: message = "リクエストに通常より時間がかかっています" 壊す; ケース TaskStatus.RanToCompletion: メッセージ = (MessageResponse) task.Result; 壊す; } メッセージを返します。 }
ノート:
タスク作成オプション None / Longrunning / PreferFairness は影響しません。ビジュアル スタジオ パフォーマンス アナライザーを実行すると、Longrunning が要求ごとに新しいスレッドを作成し (予想される)、None が限られた数 (基になるスレッドプール) を使用して要求を処理することが視覚的にわかります。
ANTS パフォーマンス プロファイラーと Visual Studio パフォーマンス アナライザーの両方を見ると、競合に関する同時実行の問題はなく、時間が浪費されている他の明白な領域 (CPU 時間またはウォール クロック時間) もありません。
視覚化された結果から明らかなことは、たとえば 1000 のリクエストがキューに入れられている状況では、プログラム時間の 90% がスレッド サービスとコンテキスト切り替えに費やされていることです。
(明らかに非常に高価です)。私の結論は、(複数のリクエストで)結果を待つことは非常にコストがかかるということです。
WebページまたはWPFフォームでこれを行うと、完全に非同期にすることができますが、このオプションはありません。
同時実行性を最適化するためにメッセージ処理メカニズムを変更できる場所はありますか? 私は本当に何に対してもオープンであり、それが有益であれば async / await を探求することさえあります。
前もって感謝します :)