私はコードが決して実行されなくても、ロックされたコードが私のコードをどのように遅くすることができるのだろうかと思います。以下はその例です:ロックされたコードによる減速を回避するにはどうすればよいですか?
public void Test_PerformanceUnit()
{
Stopwatch sw = new Stopwatch();
sw.Start();
Random r = new Random();
for (int i = 0; i < 10000; i++)
{
testRand(r);
}
sw.Stop();
Console.WriteLine(sw.ElapsedTicks);
}
public object testRand(Random r)
{
if (r.Next(1) > 10)
{
lock(this) {
return null;
}
}
return r;
}
このコードは、私のマシンで〜1300ミリ秒で実行されます。ロックブロックを取り除いても(ボディはそのままにしておくと)、750msになります。たとえコードが決して走っていなくても、ほぼダブル!
もちろん、このコードは何もしません。オブジェクトが初期化されているかどうかをコードがチェックし、初期化していない場合にはクラス内でいくつかの遅延初期化を追加していました。問題は、初期化がロックされ、最初の呼び出しの後でもすべてが遅くなることです。
私の質問は以下のとおりです。
- ですが、なぜでしょうか?景気減速を回避するために、どのよう
'lock'を集中的に使うつもりがない限り、私は本当に心配しません。 – James
同様の結果が得られますが、ティックは100 * nano *秒です。両方の実行には〜0msが必要です(つまり 'sw.ElapseMilliseconds'を出力した場合)。この" slowdown "(〜0.00006s)は' lock'に 'try/finally'ブロックが含まれている可能性が高いですメソッドが呼び出されたときのセットアップ。 'testRand'の内容をループ自体に入れてみてください。その時点ではほとんど減速しません。 – dlev
あなたは 'AggressiveInline'でメソッドをマークしようとしましたか?おそらく、ロッキングコードは、このメソッドを通常のインライン展開には大きすぎます。 .net JITterは、ILコードのサイズに基づいて、ややばかばかしいヒューリスティックを使用してインライン展開します。 – CodesInChaos