Hi Simon,
you could try a sub-library of my project, able to archive and de-archive your data in binary format. It's more low-level than Codable but it's also orders of magnitude faster.
Most system types are already implemented, and it's very easy to add implementations of others anyway.
Your code becomes:
import Foundation
import simd
class Node: BinaryIOType {
public var position : simd_float3 = [0, 0, 0]
public var name : String = "Node"
public var vertices : Array<simd_float3> = []
init() {}
// Just implement these two methods of the BinaryIOType protocol:
func write(to writer: inout BinaryWriter) throws {
try position.write(to: &writer)
try name.write(to: &writer)
try vertices.write(to: &writer)
}
// read each variable in the same order it was written
required init( from reader: inout BinaryReader ) throws {
self.position = try simd_float3(from: &reader)
self.name = try String(from: &reader)
self.vertices = try Array<simd_float3>(from: &reader)
}
}
/// Default instance
var newClassNode = Node()
/// Modified instances
var moved_newClassNode = Node()
moved_newClassNode.name = "Updated_Node_Position"
moved_newClassNode.position = [1, 1, 1]
moved_newClassNode.vertices = [ [0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4],
[5, 5, 5], [6, 6, 6], [7, 7, 7], [8, 8, 8], [9, 9, 9], ]
// You can even use Data here, but [UInt8] is faster:
var data_test = try newClassNode.binaryData() as [UInt8]
var data_test2 = try moved_newClassNode.binaryData() as [UInt8]
print( "newClassNode data: \(data_test)\n" )
print( "moved_newClassNode data: \(data_test2)\n" )
// etc....
// Of course you can recreate the value from the data:
var decoded_newClassNode = try Node(binaryData: data_test)
var decoded_moved_newClassNode = try Node(binaryData: data_test2)
extension Node: Equatable {
static func == (lhs: Node, rhs: Node) -> Bool {
return lhs.position == rhs.position && lhs.name == rhs.name && lhs.vertices == rhs.vertices
}
}
print("-- EQUALITY CHECK: ----------------------------")
print("\t• decoded newClassNode equality check = \( newClassNode == decoded_newClassNode)")
print("\t• decoded moved_newClassNode equality check = \( moved_newClassNode == decoded_moved_newClassNode)")
This is the output:
newClassNode data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 111, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0]
moved_newClassNode data: [0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 85, 112, 100, 97, 116, 101, 100, 95, 78, 111, 100, 101, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 64, 64, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 160, 64, 0, 0, 160, 64, 0, 0, 192, 64, 0, 0, 192, 64, 0, 0, 192, 64, 0, 0, 224, 64, 0, 0, 224, 64, 0, 0, 224, 64, 0, 0, 0, 65, 0, 0, 0, 65, 0, 0, 0, 65, 0, 0, 16, 65, 0, 0, 16, 65, 0, 0, 16, 65]
-- EQUALITY CHECK: ----------------------------
• decoded newClassNode equality check = true
• decoded moved_newClassNode equality check = true
If you want to give it a try, go here, select the branch IdentitySupportForValueTypes, download the files contained in GraphCodable/Sources/GraphCodable/BinaryIO/ and add they to your project.