Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 962
user1244109 Avatar asked Jan 19 '16 21:01

user1244109


3 Answers

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.

like image 179
Mirek Avatar answered Dec 15 '22 15:12

Mirek


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

like image 37
mipadi Avatar answered Dec 15 '22 17:12

mipadi


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.

like image 24
GoRoS Avatar answered Dec 15 '22 17:12

GoRoS