skip to Main Content

The cow(copy on write) doesn’t work for custom structures and basic data types(except strings), but I’m wondering why. Can I know the relevant reference?

I learned that when copying a value called cow, it is a memory-saving technique by sharing the original until one of the values modifies it. However, as far as I know, the type that cow works is limited to the collection type only. Is this because cow works optimally when dealing with large amounts of data? Also, why doesn’t cow work when copying custom structures or basic data types?

2

Answers


  1. AFAIK, copy-on-write is used to optimize performance, thus, it should affect the data structure which could potentially cost a lot of memory. To match with this proposal, there are array, string, dictionaries, etc.

    Btw, you can absolutely implement copy-on-write by yourself with isKnownUniquelyReferenced. For more information, check this.

    Login or Signup to reply.
  2. Just in case you are confused, CoW is not a language feature. It is an optimisation that is implemented by whoever wrote Array/Dictionary/String.

    So CoW doesn’t work for your own structs, simply because you haven’t implemented CoW.

    For the built-in collections with CoW, they all store a reference to an instance of a class, and that class is what actually holds the contents of the collections. e.g. for arrays, this class is __ContiguousArrayStorageBase. When you modify the collection, isKnownUniquelyReferenced is called to check if there are more than one references to that class instance. If that is the case, then a copy of that instance is made, effectively copying the whole storage of the collection.

    let x = [1,2,3]
    // isKnownUniquelyReferenced is true for x's storage here - only x is referencing that storage
    var y = x
    // isKnownUniquelyReferenced is false here - both x and y are referring to the same storage
    y.append(4) // a copy of the storage is made here, because y is modified
    

    The "optimisation" here is that var y = x does not copy the whole storage of the array. It only copies the reference to __ContiguousArrayStorageBase.

    If you want CoW on your own structs, you can implement something similar.

    Understanding that, it should now be obvious why CoW is not implemented for types like Int or Bool. It is exactly as you said:

    Is this because cow works optimally when dealing with large amounts of data?

    The point of CoW is to avoid copying a large amount of data when you do var y = x (or similar). If copying the whole value itself is not expensive, then there is no point in CoW, which would just add more overhead instead.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search