Interlocked.Increment vs. lock – surprise surprise !

   edit
Follow


 

Problem at hand: an ID generator.

 

Like many other things, developers can be categorized into three types : *

Now I am definitely not a concurrency guru like myteammates, however when I looked at a code for an ID generator that had

public int GetNextId() {
	lock(locker)
		return nextId++;
}

I immediately ran a git-checkout, changed that offending piece of code to

public int GetNextId() {
	return Interlocked.Increment(ref nextId) – 1;
}

And created a patch to send to the innocent owner of the code.

 

Smart heh? **

 

Then I thought that it won’t hurt to throw in a little proof for this amazing improvement.

Running 1000 calls to a GetNextId that was using a lock, took longer than calling the method using Interlocked !  Ah Ha – who’s the man?

 

Then I realised that a better test will be to run these 100 calls in parallel. That is after all the whole idea of a shared generator. Many threads might need to call it on the same time !

 

To my surprise, when asking for IDs in parallel, the interlocked construct was almost always slower, taking about 150% of the time the lock construct took on most runs (I tried this again and again, every time averaging 100 repeats).

 

Here’s a screenshot of the test run

interlocked vs lock

 

Code is here: https://gist.github.com/24b9012a49392c4e458b

 

After thinking about this a little, I think that I have an idea why this is happening, assuming my SpawnAndWait call is not entirely stupid (is it?)

 

So I call you my dear readers (most of which are way smarter than I am): what is your take on that? why did that happen? and would you have chosen lock or interlocked for an ID generator?

 

 

** probably not


     Tweet Follow @kenegozi