I have structs like
struct RGBA: Codable {
var r: UInt8
var g: UInt8
var b: UInt8
var a: UInt8
}
I want save large amou
The performance of JSONEncoder
/Decoder
performance is...not great. ZippyJSON is a drop-in replacement that is supposedly about 4 times faster than Foundation's implmenetation, and if you're going for better performance and lower memory usage, you'll probably want to Google for some kind of streaming JSON decoder library.
However, you said in the comments that you don't need the JSON format. That's great, because we can store the data much more efficiently as just an array of raw bytes rather than a text-based format such as JSON:
extension RGBA {
static let size = 4 // the size of a (packed) RGBA structure
}
// encoding
var data = Data(count: history.rgba.count * RGBA.size)
for i in 0..
This is already about 50 times faster than using JSONEncoder on my machine (~100ms instead of ~5 seconds).
You can get even faster by bypassing some of Swift's safety checks and memory management and dropping down to raw pointers:
// encoding
let byteCount = history.rgba.count * RGBA.size
let rawBuf = malloc(byteCount)!
let buf = rawBuf.bindMemory(to: UInt8.self, capacity: byteCount)
for i in 0..
Benchmark results on my machine (I did not test ZippyJSON):
JSON:
Encode: 4967.0ms; 32280478 bytes
Decode: 5673.0ms
Data:
Encode: 96.0ms; 4000000 bytes
Decode: 19.0ms
Pointers:
Encode: 1.0ms; 4000000 bytes
Decode: 18.0ms
You could probably get even faster by just writing your array directly from memory to disk without serializing it at all, although I haven't tested that either. And of course, when you're testing performance, be sure you're testing in Release mode.