I debugged my test and found one of the major contributor to slowness in the Codable based serialiser:
class MyEncoder: Encoder {
...
func encode(_ value: Float) {
...
}
func encode<T: Encodable>(_ val: T) {
try! val.encode(to: self)
}
....
private struct KeyedContainer<Key: CodingKey>: KeyedEncodingContainerProtocol {
var myEncoder: MyEncoder
func encode<T: Encodable>(_ value: T, forKey key: Key) {
myEncoder.encode(value)
}
...
}
...
}
Stepping through the line "myEncoder.encode(value)" where the value passed was Float, the resulting "encode" method being called was not the specialised "encode(_ value: Float)" but generic "encode<T: Encodable>(_ val: T)" (why it is this way is discussed here). I put the workaround and interestingly that one change sped the serialised 10 times, so now my codable based serialised is just 10x slower than the manual serialiser.