Will this cause unnecessary COW?

Hey everyone

So I was wondering, if I copy an array from a dictionary value, then mutate it, and then reassign it to the dictionary value, this will cause COW and the existence of 2 array underlying storages at the same time for a brief period of time?

And in order to avoid it, I should never make a copy of a value from the dictionary and instead modify it in place, right?

Take a look at this code:

// Two backing storages will exist at the same time because COW because there are 2 strong refs
var oldReports = state.database.reports[id] ?? []
oldReports.append(report)
state.database.reports[id] = oldReports

// No COW since there is only one retain by the dictionary
if state.database.reports[id] == nil {
    state.database.reports[id] = [report]
} else {
    state.database.reports[id]!.append(report)
}

Or there is something I'm not seeing, and actually this will be optimized away by the compiler?

Correct, this will CoW. The bottom code sample will not. You can consider making extension methods on Optional or using the subscript with default if you want to make the code at the bottom cleaner and avoid hashing the key twice.

3 Likes

daaaam that's pretty cool

1 Like

The subscript that takes a default value could help here:

state.database.reports[id, default: []].append(report)
3 Likes