[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sync.m

From: David Chisnall
Subject: Re: sync.m
Date: Sat, 27 Feb 2010 18:39:27 +0000

I've now fixed this case in libobjc2.  Unfortunately, someone decided to 
'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which 
means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to 
diffs against the original version in √Čtoil√© svn), so whoever did that gets to 
volunteer to back-port the changes.  

On 27 Feb 2010, at 17:40, Richard Frith-Macdonald wrote:

> You are probably in a better position than anyone else to be aware of 
> precisely what parts of ObjectiveC-2 are most efficient or inefficient, and 
> how they compare to the traditional ways of doing things.  Have you 
> considered producing a paper describing those differences?  If we had them 
> quantified we would have a really good guide for people to know when to use 
> new features and when to avoid them (and when it really doesn't matter).

Well, I did write a book that describes them...

@synchronized is basically impossible to implement efficiently.  It's a stupid 
feature added to make life easier for Java programmers who are too lazy to 
think when they learn a new language.  There are basically three ways you can 
do it:

1) Allocate a pthread_mutex_t with every object

Pros: Fast, simple
Cons: Wastes at least one word of memory for every object, including the 99.9% 
that are never used as arguments to @synchronized().

2) Have a shadow data structure mapping objects to locks.

Pros: Doesn't waste much memory.
Cons: Extra locking on the shadow structure needed, extra code needed to remove 
locks when they are no longer needed, overhead performing the lookup.

3) Add a hidden class between the object and its real class which stores the 

Pros: Relatively simple and non-invasive.
Cons: Needs an extra class structure for every locked object.

libobjc2 / ObjectiveC2.framework use option 3.  We use 
objc_allocateClassPair(), which doesn't work for creating just a new metaclass 
(although we fail slightly more gracefully than Apple's version, which just 
returns a pointer to a random address).  I've now added a special case to 
libobjc2 and a non-portable runtime function for allocating just a new 

In all cases, this pattern will be much faster:

[nslock lock];
@try {
        // do stuff
} @finally {
        [nslock unlock];

It's also worth remembering that @synchronized uses a recursive mutex, which, 
on most platforms, is slower than the non-recursive form used by NSLock.  
Unless you actually need the recursive behaviour, don't use it.  

@synchronized is a horrendous language feature, because it looks just like the 
Java keyword, but has almost the exact opposite performance characteristics.  


-- Sent from my Difference Engine

reply via email to

[Prev in Thread] Current Thread [Next in Thread]