Synchronization vs atomicReference performance test

Are “Lock free” structures necessarily more performant (quicker) than the traditional approach to synchronization, relying on locks ? How does the number of threads impact performance ?It’s time for a little speed test.

speed

An AccountDate class (a simple wrapper around a Date)  is updated 1,000,000 times in two scenarios:

– scenario 1: 20 threads updating an accountDate instance 50,000 times.
– scenario 2: 2 threads updating an accountDate instance 500,000 times.

Within each scenario, three different objects are used to execute the update.

– The SimpleAccountDate updater acts a baseline. It does not use synchronization at all, which will lead to a race condition (most probably)

– AccountDateSynchronized uses the synchronized keyword to serialize access by the threads to the content of the AccountDate.

– AccountDateAtomicRef uses a lock free AtomicReference and CAS to update the underlying AccountDate.

results with 20 threads

SimpleAccountDate in 14 ms race condition
AccountDateSynchronized in 68 ms OK
AccountDateAtomicRef in 119 ms OK

results with 2 threads

SimpleAccountDate in 13 ms race condition
AccountDateSynchronized in 63 ms OK
AccountDateAtomicRef in 60 ms OK

Unsurprisingly the SimpleAccountDate is very fast (but wrong). Performance under synchronization degrades only very slightly with the number of threads, while the CAS strategy does not scale nearly as well. This can be explained by the higher number of threads causing higher contention on a single accountDate object, with many threads simultaneously attempting to update this object, but only one thread at at time managing to do so.

The code source

Advertisements

3 thoughts on “Synchronization vs atomicReference performance test

  1. Xenega

    Your tests are not fair. AccountDateAtomicRef create a new Date object, but the others just update the old with a method. Create a object is very costly, so you are benchmarking the cost of using a new object, not the cost of atomic reference.

    Reply
      1. Xenega

        I already know this link. The cost of new is very low, but not low in case of micro-optimization. Cost comparison depends of the context. In some context where VM resources are very scarce, it become a important problem (see android optimization https://developer.android.com/training/articles/perf-tips.html ). Comparing synchronization and AtomicReference is a kind of micro-optimization, so creating a object isn’t free and must be taken into consideration. You are testing synchronized vs AtomicReference, not AtomicReference + new. You benchmark very simple and not CPU intensive operations, each one counts.

        However, I’ve modified your benchmarks so AccountDateSynchronized also create an object. The penalty for AccountDateSynchronized is important but not enough to overcome the conclusion of the article. I would recommend you to test it yourself and update your article.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s