user1244109
user1244109

Reputation: 2186

Is accessing NSUserDefaults on iOS considered cheap?

In short: is it fast/cheap? Does it make sense to store a value from NSUserDefaults in memory for faster access?

Longer: say, i have significant number of values to be stored and read from NSUserDefaults; with the need to access(read) those values frequently.

In the snippet below, i initialize a private stored property, and keep it synced with corresponding NSUserDefaults value - so when i need to read it, i read the property.

If reading from the defaults directly is in fact fast, i'd remove the private property, obviously. But i'm unsure of that. Is it fast?

private var _loggedIn = NSUserDefaults.standardUserDefaults().boolForKey("loggedIn")
public var loggedIn: Bool {
    get {
        return _loggedIn
    }
    set {
        _loggedIn = newValue
         NSUserDefaults.standardUserDefaults().setBool(newValue, forKey: "loggedIn")
         NSUserDefaults.standardUserDefaults().synchronize()
    }
}

Clarification for future readers: the question is about reading, not writing/synchronizing, which is (as pointed in the answers) not fast nor cheap.

.synchronize() is called in the setter for a valid reason - in my specific case it is important to have it synched right away, so i sacrifice performance for logic integrity. In general cases, you should consider whether you need to call it - or let the system pick appropriate time for writing.

..In fact, now that i look at it, i see keeping the stored property as it is in the snippet, will provide logic integrity (as long as access from other places happens via the getter, and not directly from userDefaults). So i can avoid synchronizing here as well.

Upvotes: 6

Views: 777

Answers (4)

gnasher729
gnasher729

Reputation: 52632

It's all fine unless you use NSUserDefaults as a database. synchronize () will write the complete plist file, so if you store megabytes of data, and then synchronize a lot, performance and/or battery life will suffer.

But check out this question as well: How often are NSUserDefaults synchronised?

An interesting detail is that user defaults will be written when your application terminates. Someone might experiment what happens if your program crashes right after changing NSUserdefaults; if that counts as "termination".

Upvotes: 0

Mirek
Mirek

Reputation: 500

Reading is cheap. There is a generous caching in place and everything happens in RAM. Mutating is relatively cheap, but the system will still have to store the contents to non-volatile memory (a .plist file on the flash) at regular intervals.

Explicit synchronising isn't cheap. It eats time and more energy.

So for reads it is fine, but with a lot of writes I would still do it in a separate container and serialise only as needed.

Upvotes: 9

GoRoS
GoRoS

Reputation: 5375

I made some performance tests with Instruments as @mipadi has suggested the past year and my conclusion was there is no substantial difference.

As I pointed out in a comment above, it's very important to detect which of those NSUserDefaults writes we want to be done straightaway. Just in those particular cases use synchronize method, otherwise leave iOS to handle that work to obtain better performance.

Upvotes: 1

mipadi
mipadi

Reputation: 411340

It's unlikely to have a significant performance impact, but you can profile that yourself using Instruments to ensure the performance impact is negligible.

Upvotes: 2

Related Questions