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

Colin Barrett timber at lava.net
Tue Apr 4 19:41:27 UTC 2006


On Apr 4, 2006, at 1:56 PM, Evan Schoenberg wrote:

> 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:
> <AIPreferenceController.h>
> <AIPreferenceController.m>
>
> The diff:
> <AIPreferenceController+NSUserDefaults.diff>
>  -- 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

Here are a couple of thoughts:

  - What if you had a separate user defaults file for each group?  
com.adiumX.adiumX.contacts, for example.
  - Can we convert our current implementation over to binary plists?
  - I know Evan doesn't "get my Core Data hard-on" ;), but it's too  
bad we can't use Core Data for this. Would be nearly instantaneous,  
and would probably be real fast too. Something like  
AIPreferenceProxy, but it'd be called AIManagedPreference.

I have a couple general questions about the prefs system too. How bad  
is it, right now? Does it need cleaning up? I know this code is some  
of the oldest in Adium, I think it's a good idea to at least do a  
small audit of the state of things in there.

-Colin




More information about the devel mailing list