'Is the "lock" statement in C# time-consuming?

I have a method which has been called many times by other methods to hash data. Inside the method, some lock statements are used. Could you please let me know whether the lock statement is time-consuming and what is the best way to improve it.

P/S: I have been finding a way to avoid using the lock statement in this method.



Solution 1:[1]

The lock statement itself is not very time-consuming, but it may cause contention over shared data.

Followup: if you need to protect shared data, use a lock. Lock-free code is wicked difficult to do correctly, as this article illustrates.

Solution 2:[2]

You might find this article on threads interesting and relevant. One of the claims that it makes is "Locking itself is very fast: a lock is typically obtained in tens of nanoseconds assuming no blocking."

Solution 3:[3]

The lock statement itself is actually some syntactic sugar that creates and manages a Monitor object.

This in itself is usually not overly resource intensive, but can become a problem if you have multiple reads but no writes to your variable across multiple threads. Each read will have to wait for the other to finish before a read can complete. In scenarios where you might be getting the variable from multiple threads, but not setting it, you might want to look at using a ReaderWriterLockSlim object to manage asynchronous reads and writes.

Solution 4:[4]

I landed here for a slightly different question. In a piece of code that can be run as single threaded or multi threaded shoud I refactor the code to remove the lock statement (i.e. is the lock statement without parallelism costless)?

This is my test

class Program
{
    static void Main(string[] args)
    {
        var startingTime = DateTime.Now;
        (new Program()).LockMethod();
        Console.WriteLine("Elapsed {0}", (DateTime.Now - startingTime).TotalMilliseconds);
        Console.ReadLine();
    }

    private void LockMethod()
    {
        int a = 0;
        for (int i = 0; i < 10000000; i++)
        {
            lock (this)
            {
                a++; // costless operation
            }
        }
    }
}

To be sure that this code is not optimized I decompiled it. No optimizations at all (a++ changed to ++a).

RESULT: 1Mln of not contended locks acquirements takes about 160ms that is about 15ns for acquire a not contended lock.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stephen Cleary
Solution 2 Mike Chess
Solution 3 Kevin McKelvin
Solution 4 bubi