In my application, I need to store millions of custom structs that contain 2 UUID attributes to disk. My project requires these to be written & read to disk very quickly. I tried using JSONDecoder but found the performance to be very slow for saving around 100k to around 10 million of these structs which took from anywhere around 3 to 30 seconds as tested thoroughly.
Is there a much more efficient way to store a struct with just 2 UUIDs such as using a binary representation? I was unable to find any resources on saving UUIDs to disk. I do not need the format to be JSON for both saving to and reading from disk.
struct MetadataItem: Identifiable, Codable {
var id = UUID()
let itemId: UUID
}
//Just to simulate adding the custom structs
for i in 1...1000000 {
let newItem = MetadataItem(itemId: UUID())
metadataItems.append(newItem)
}
do {
let data = try JSONEncoder().encode(metadataItems)
if let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
try data.write(to: url.appending(path: "Metadata"))
}
print("Done")
} catch {
}
If anyone is wondering, after testing myself more versions of the method as suggested by "workingdog", it is magnitudes more faster to convert the UUIDs to Data using the .uuid property and then writing to disk compared to using the string version instead.
After testing, this is what I got for storing 1 million of these structs to disk from slowest to fastest...
PropertyListEncoder: 4.46s
JSONEncoder: 3.37s
Converting UUID to string: 1.13s
Converting UUID to uuid data bytes: 345ms
func metadataItemsToBinary(items: [MetadataItem]) -> Data {
var data = Data()
for item in items {
data.append(withUnsafeBytes(of: item.id.uuid) { Data($0) })
data.append(withUnsafeBytes(of: item.itemId.uuid) { Data($0) })
}
return data
}