Corbin Dunn
Redwood Monkey

Cocoa programmers: avoid writing to the user defaults when you don’t need to

Cocoa, Coding

[Edit: ecto ate this post, so I’m typing it in again!]

I discovered that a lot of applications will unnecessarily write to NSUserDefaults. This causes your app to hit the disk when it shouldn’t, and is a slight performance penalty. AppKit is also susceptible to this problem; if you hit cmd-O to bring up the open panel in any application, you will see it writing things to the user defaults, when it probably doesn’t need to do so. I’m working on fixing that, and you should to!

So, how do you do it? It is easy — just add a breakpoint on -[NSUserDefaults(NSUserDefaults) setObject:forKey:]. You can do this with gdb:

b -[NSUserDefaults(NSUserDefaults) setObject:forKey:]

Or you can use the breakpoints window in Xcode (my preferred way):

Picture4 - breaking on user defaults.png

Then, reproduce whatever action might cause it to happen (ie: starting your application, or in my test case, cmd-o to bring up the open panel). Look at the backtrace in Xcode and figure out why you are doing too much work:

Picture5 - the callstack for a user default.png

Previous Post
Post muni pizza
Next Post
Greener AAPLs

10
Leave a Reply

avatar
500
10 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
5 Comment authors
StephanePatrick Machielseleegcorbincorbin Recent comment authors
  Subscribe  
Notify of
Daniel Jalkut
Guest

It should only be hitting disk when -[NSUserDefaults synchronize] is called, shouldn’t it? App developers should be able to safely assume that writing the defaults is cheap and efficient, and should be callable all the time with essentially the cost of writing to a dictionary.

If NSUserDefaults is hitting the disk before synchronize is called, It would be a better use of time to fix it so that it fulfills the contract (if it, in fact, doesn’t), than to encourage developers everywhere to work around a system performance issue by changing their own code.

Patrick Machielse
Guest

Hmm, I think this is a prime example of ‘premature optimization’. Anno 2008, ‘hitting the disk’ is dirt cheap (in fact, I believe it even gives back change nowadays…). How long does it take to save the defaults file? (you measured this before taking the time to optimize, of course ;-)) According to the documentation -[NSUserDefaults synchronize] is called automatically at set intervals, and in my experience it seems that the plist file is updated automatically within a very short time of changing a preference (either in code or as a result of resizing a window frame…). If you are… Read more »

corbin
Guest

Patrick — you are very right. It is a small optimization, but I wouldn’t call it premature. It was established after looking at applications and the disk activity that they do when launching, or doing certain activities. In day to day programming, it isn’t something to really worry about. If you consider the particular case I’m attempting to make faster, which is the bring up of the open or save panel, then it makes sense to avoid unnecessary disk hits. However, there are other factors that slow the panel down; one such case is the spin up of disks to… Read more »

leeg
Guest

So when it comes to NSUserDefaults, do people consider the defaults domain part of the “user interface” of the application? My opinion often wanders between “yes, power users could enable hidden features through the defaults interface” and “the user shouldn’t touch it, but if they break it I should be able to carry on” but never gets as far as “no”. I’d be interested to hear what other people think :-)

Patrick Machielse
Guest

Corbin – I still don’t really believe that reading or writing a 4k or 8k text file now and again is going to have an impact on the user experience. If users choose to spin down the drive that contains their home directory (if this would really slow down the drop down speed), well, it’s their decision…

There is (or at least was) a global setting (in the user defaults of course!) that effects the sheet animation speed . Not sure if you could (you probably can) or should override this on a per application basis.

stephane
Guest
stephane

Could it be possible to put back the ability to see invisible items in NSOpenPanel/NSSavePanel while devastating this part of the AppKit?

corbin
Guest

Patrick — other considerations are things like network home directories, which some people at apple still use (I occasionally use mine for various testings or when logging onto other machines). Still, it is a minor optimization, and I still think it is good practice to not right out things you don’t need to. It is sort of akin to writing out things into a Delphi form (a related but similar example). Why right out things you don’t need to? For this purpose, we had default values that could be used (and not written out) when the form was saved to… Read more »

Stephane
Guest
Stephane

“NSSavePanel and NSOpenPanel can once again show hidden files by setting a user default.”

Why is is not listed in the 300+ new features on the Mac OS X front page? There should even be a PC/Mac ad for this.

Release Notes is such a modest spot to list the return of this feature that I didn’t find it when I read them quickly a long time ago.

(c) 2008-2018 Corbin Dunn

Privacy Policy

Subscribe to RSS feeds for entries.

82 queries. 0.383 seconds.

Log in