[Adium-devl] Using NSUserDefaults for preferences (or not)

Evan Schoenberg evan.s at dreskin.net
Tue Apr 4 17:56:44 UTC 2006


We've discussed off and on for a long time the possibility of  
switching to NSUserDefaults for our preferences rather than our own  
dictionary plist reading/writing.  Yesterday, I decided to implement  
it.  The initial implementation seemed really good and fast -- we got  
to cut out a bunch of code as well as rely on NSUserDefaults for  
writing out our preferences a brief delay after changes, allowing for  
fast nonblocking preference changes.  I liked it enough to write a  
preference importer for 0.8x --> 1.0, which is run on first launch of  
1.0... and that's when things got ugly.

In separate plist form, I currently have: 236 kb of root plists, 10.8  
MB of plists in ByObject, and 520 kb of plists in Accounts.  The  
largest single plist is 80 kb (Account Status.plist), with an average  
size of 4 kb.  Reading and writing of the plists is nearly  
instantaneous...

NSUserDefaults took all this data and made a 1.7 MB  
com.adiumX.adiumX.plist file (in binary plist form).  The problem is  
that it appears that NSUserDefaults has to read the entire file in to  
use it -- unsurprising, since it's a binary plist -- and therefore  
delays a looong time at startup and then at the first call to - 
[NSUserDefaults objectForKey:] after a preference changes... and  
writing doesn't appear to be cheap at this file size, either.  Out of  
curiosity, I tried to load the file into the Property List Editor...  
it has 7838 key/value pairs and took about 10 minutes to toggle to  
Root item.

The AIPreferenceController itself: 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: AIPreferenceController.h
Type: application/octet-stream
Size: 4919 bytes
Desc: not available
URL: <http://adium.im/pipermail/devel_adium.im/attachments/20060404/baea68bf/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: AIPreferenceController.m
Type: application/octet-stream
Size: 23315 bytes
Desc: not available
URL: <http://adium.im/pipermail/devel_adium.im/attachments/20060404/baea68bf/attachment-0001.obj>
-------------- next part --------------

The diff: 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: AIPreferenceController+NSUserDefaults.diff
Type: application/octet-stream
Size: 36264 bytes
Desc: not available
URL: <http://adium.im/pipermail/devel_adium.im/attachments/20060404/baea68bf/attachment-0002.obj>
-------------- next part --------------
  -- this includes some changes elsewhere which were intended to  
improve efficiency, since preferencesForGroup: is highly inefficient  
in the new implementation.  I added a class AIPreferenceProxy which  
acts like an NSDictionary for preference access via the new system,  
used in places that the same preference group is accessed tons of  
times in a row.  It's no more efficient than preferenceForKey:group:  
but lets the code elsewhere be cleaner.

Thoughts?

-Evan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
URL: <http://adium.im/pipermail/devel_adium.im/attachments/20060404/baea68bf/attachment.sig>


More information about the devel mailing list