Fastest way to save structs iOS / Swift

后端 未结 2 1170
孤街浪徒
孤街浪徒 2021-01-20 16:38

I have structs like

struct RGBA: Codable {
        
   var r: UInt8
   var g: UInt8
   var b: UInt8
   var a: UInt8 
}

I want save large amou

2条回答
  •  不思量自难忘°
    2021-01-20 17:29

    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.

提交回复
热议问题