Performance implications of declaring Array/Dictionary property requirements in a protocol

are there any important performance issues to be aware of when using protocol members of Array<T> or Dictionary<Key, Value> types from within a protocol extension?

protocol Foo 
{
    var dictionary:[Int: String]
    {
        get set 
    }
}
extension Foo 
{
    mutating 
    func bar(x:Int, y:String) 
    {
        self.dictionary.updateValue(y, forKey: x)
    }
}

This code is fundamentally flawed, as it will trigger CoW on the dictionary on every call to bar. I don't know if invoking the get/set via the witness table when the concrete type isn't known at compile time, or executing it generically if it hasn't been specialized, is especially worse in any particular way other than it lessens what chance there is to optimize away that fundamental problem (which is rare anyway).

2 Likes

how can i prevent copy-on-write from happening here? will changing set to _modify be enough to fix this problem?

Should be, yes. Bearing in mind _modify is unofficial and has no source stability guarantees.

1 Like

what about a requirement such as

protocol Foo 
{
    func withDictionaryStorage(_ body:(inout:[Int: String]) -> ())
}

?