@synchronized vs dispatch_once

In the comments on a recent Stack Overflow question, someone asked me if there was a significant performance difference between @synchronized and dispatch_once in implementing a singleton. So I wrote a simple test harness to access a singleton using the @synchronized method shown here:

@synchronized(self) {
if (!synchronizedVar) {
synchronizedVar = [[Test alloc] init];
return synchronizedVar;

and the dispatch_once method shown here:

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dispatchVar = [[Test alloc] init];
return dispatchVar;

Each test accessed the singleton object 10 million times. I ran both single-threaded tests and multi-threaded tests. Here were the results:

Single threaded results
@synchronized: 3.3829 seconds
dispatch_once: 0.9891 seconds

Multi threaded results
@synchronized: 33.5171 seconds
dispatch_once: 1.6648 seconds

So yeah, dispatch_once is a lot faster, especially under thread contention. You can find my test harness on github.

2 responses to “@synchronized vs dispatch_once”

  1. But you have to remember that you are comparing apples to oranges. dispatch_once is great for those situations where you know you only need to do something once, but in situations where you need to repeatedly check for race conditions (such as atomic properties), @synchronized is the clear winner. So, it really is situation dependent and the two cannot be compared.


  2. Absolutely; dispatch_once applies to a much smaller set of cases. But the Stack Overflow question which prompted the question was asserting that initializing a singleton was just as fast either way, which is clearly not the case.


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 )

Connecting to %s

%d bloggers like this: