Monday, February 4, 2013

Persisting Objects: NSArchiver vs JSON

There are many ways to store data persistently in iOS. One common technique is to archive (serialize) objects using an NSArchiver. Archiving has always seemed slower than I expected and recently I began to wonder if it might be faster (or slower) to instead convert an object to JSON and write that out instead?

Tonight I ran a simple experiment to get a rough and unscientific approximation. You should consider this anecdotal.

The test was pretty straightforward. First I loaded up an NSDictionary with lots and lots of data and then measured the time it takes to write it and read it using both archiving and JSON-ifying. I also measured the size of the output files to see how they compare.

For archiving I simply used +[NSKeyedArchiver archiveRootObject:(id)rootObject toFile:(NSString *)path] and +[NSKeyedArchiver unarchiveObjectWithFile:(NSString *)path];

For JSON I used JSONKit and basic methods to read and write an NSString to and from a file.

The difference in the results was much larger than I expected. Using JSON was the clear winner in my tests. First it produced a file that was 3X smaller than the binary archive. Reading the data was about 3X faster too. The largest performance gain came from writing the data. Converting an object to JSON and writing it out was about 10-15X faster than using NSKeyedArchiver.

Below are the results on 4 different pieces of hardware (one of which was the iPhone simulator on a MBP).

The bottom line here is that if you are archiving "simple" objects (objects that can be easily represented as JSON, no cycles, etc...) you should strongly consider storing JSON instead of archiving.

Size of output file - 3X improvement

NSArchiver JSON
28 MB 10 MB

Time to write to disk - 10-15X improvement

NSArchiver (archive to file) JSON (convert object to JSON + write to file)
iPhone Sim on MBP 3.58 seconds .23 seconds
iPhone 5 19.68 seconds 1.29 seconds
iPhone 4S 36.66 seconds 3.3 seconds
iPhone 4 62.65 seconds 4.51 seconds

Time to read from disk - 3X improvement

NSArchiver (unarchive from file) JSON (read file + convert JSON to object)
iPhone Sim on MBP 1.4 seconds .4 seconds
iPhone 5 7.84 seconds 2.78 seconds
iPhone 4S 15.29 seconds 5.83 seconds
iPhone 4 25.18 seconds 7.9 seconds

No comments: