プロジェクトをリファクタリングしようとしていますが、現在、アプリケーションのパフォーマンスを向上させる最善の方法を研究しようとしています。
質問 1. スピンロックとインターロック
カウンターを作成するには、どちらの方法がパフォーマンスが優れているか。
Interlocked.increament(ref counter)
または
SpinLock _spinlock = new SpinLock()
bool lockTaken = false;
try
{
_spinlock.Enter(ref lockTaken);
counter = counter + 1;
}
finally
{
if (lockTaken) _spinlock.Exit(false);
}
また、 のように別のカウンターをインクリメントする必要がある場合、別のオブジェクトcounter2
を宣言する必要がありますか? または別のオブジェクトSpinLock
を使用するのに十分ですか?boolean
質問 2. ネストされたタスクまたはより良い置換の処理
このアプリケーションの現在のバージョンでは、タスクを使用し、新しいタスクをそれぞれ配列に追加してから、Task.WaitAll()
多くの調査の結果、使用したParallel.ForEach
方がパフォーマンスが向上することがわかりましたが、現在のスレッドの数を制御するにはどうすればよいですか? MaxDegreeOfParallelism
パラメータで aを指定できることはわかっていParallelOptions
ますが、問題はここにあります。メソッドが実行されるたびにcrawl(url)
、別の限られた数のスレッドが作成されるだけです。つまり、MaxDegree
10 に設定すると、実行するたびcrawl(url)
に別の +10 が作成されます。どうすればこれを防ぐことができますか?Parallel の代わりにセマフォとスレッドを使用する必要がありますか? それとももっと良い方法がありますか?
public void Start() {
Parallel.Invoke(() => { crawl(url) } );
}
crawl(string url) {
var response = getresponse(url);
Parallel.foreach(response.links, ParallelOption, link => {
crawl(link);
});
}
質問 3. すべてのジョブ (およびネストされたジョブ) が終了したときに通知します。
最後の質問は、すべてのジョブがいつ終了したかをどのように理解できるかということです。