I was testing how Interlocked.Increment
and lock
behave on my computer's architecture because I read the following lines in this article.
As rewritten with Interlocked.Increment, the method should execute faster, at least on some architectures.
Using the following code I get convinced that it's worth to review locks in my projects.
var watch = new Stopwatch();
var locker = new object();
int counter = 0;
watch.Start();
for (int i = 0; i < 100000000; i++)
{
lock (locker)
{
counter++;
}
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds);
watch.Reset();
counter = 0;
watch.Start();
for (int i = 0; i < 100000000; i++)
{
Interlocked.Increment(ref counter);
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds);
I'm getting stable results with approximate values 2.4s for locking and 1.2s for Interlocked. However I was surprised to discover that running this code in release mode improves value only for Interlocked to approximately 0.7s and the locking time remains the same. Why is that? How is Interlocked optimized when in release mode that lock is not?