なぜロックはMonitor.TryEnterよりずっと遅いのでしょうか? 質問する

なぜロックはMonitor.TryEnterよりずっと遅いのでしょうか? 質問する

結果

ロック: 85.3 マイクロ秒

Monitor.TryEnter: 11.0 マイクロ秒

ロックは同じコードに拡張されませんか?

編集: 1000 回の反復の結果: Lock: 103.3 マイクロ秒 Monitor.TryEnter: 20.2 マイクロ秒

コードは以下です。ありがとうございます

    [Test]
    public void Lock_Performance_Test()
    {
        const int lockIterations = 100;

        Stopwatch csLock = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; )
        {
            lock (object1)
            {
                i++;
            }
        }
        csLock.Stop();

        Stopwatch csMonitor = Stopwatch.StartNew();
        for (int i = 0; i < lockIterations; )
        {
            if (Monitor.TryEnter(object1, TimeSpan.FromSeconds(10)))
            {
                try
                {
                    i++;
                }
                finally
                {
                    Monitor.Exit(object1);
                }
            }
        }
        csMonitor.Stop();

        Console.WriteLine("Lock: {0:f1} microseconds", csLock.Elapsed.Ticks / 10M);
        Console.WriteLine("Monitor.TryEnter: {0:f1} microseconds", csMonitor.Elapsed.Ticks / 10M);;
    }

ベストアンサー1

答えは分かりませんが、それを指摘することは重要だと感じていlockますMonitor.TryEnterない機能的に同等。MSDNドキュメントMonitor.TryEnter:

成功した場合、このメソッドは obj パラメータの排他ロックを取得します。このメソッドは、ロックが使用可能かどうかに関係なく、すぐに戻ります。

このlock文は と類似しておりMonitor.Enterするlock潜在的にブロックします。確かに、サンプル コードでは、ブロッキングの問題は発生しないはずですが、はブロッキングを提供するため、 よりも (潜在的に) 少し多くの作業が発生すると思いますTryEnter


参考までに、あなたのコードを自分のマシンで試してみたところ、完全に異なる結果:

100回の反復:
lock: 4.4マイクロ秒
Monitor.TryEnter: 16.1マイクロ秒
Monitor.Enter: 3.9マイクロ秒

100000回の繰り返し:
lock: 2872.5マイクロ秒
Monitor.TryEnter: 5226.6マイクロ秒
Monitor.Enter: 2432.9マイクロ秒

lockこれは私の最初の推測を深刻に覆し、私のシステム(とほぼ同じパフォーマンスMonitor.Enter)では、実際には大幅に優れている Monitor.TryEnter


実際、私は VS 2010 で .NET 3.5 と .NET 4.0 の両方を対象にこれを試してみましたが、結果は異なっていたものの、いずれの場合もlock実際には優れたパフォーマンスを発揮しましたMonitor.TryEnter

ランタイムバージョン: 2.0.50727.3603

100 回実行し、毎回 100000 回の反復を実行しました。
ロック: 279736.4マイクロ秒
モニター.TryEnter: 1366751.5マイクロ秒
Monitor.TryEnter (タイムアウトなし): 475107.3 マイクロ秒
Monitor.Enter: 332334.1 マイクロ秒

ランタイムバージョン: 4.0.30128.1

100 回実行し、毎回 100000 回の反復を実行しました。
ロック: 334273.7マイクロ秒
モニター.TryEnter: 1671363.4マイクロ秒
Monitor.TryEnter (タイムアウトなし): 531451.8 マイクロ秒
Monitor.Enter: 316693.1 マイクロ秒

Monitor.TryEnterタイムアウトなしでもテストしたことに注目してください。Marcの意見に同意したので、呼び出しはTimeSpan.FromSeconds間違いなく時間を遅くするだろうと考えたのですMonitor.TryEnter。そして、これらのテストはそれを裏付けています。しかし、あなたのどうやらこのケースlockまだ大幅に遅くなります。

これらの結果に基づいて、このコードを属性付きで実行することによって、測定された実行時間が何らかの影響を受けると強く信じていますTest。あるいは、このコードは私が予想していたよりもはるかにマシンに依存しているのかもしれません。

おすすめ記事