Copy-On-Write in Swift

Steve Dao
NE Digital
Published in
3 min readMar 11, 2020

--

Cầu Vàng (Golden Bridge) in Da Nang, Vietnam
Cầu Vàng (Golden Bridge) in Da Nang, Vietnam

Copy-On-Write is a common computing technique that helps boost performance when copying structures. Today I would like to show you how can we apply it to Swift.

As far as we know that there’re 2 types in Swift: Reference type & Value type. When we assign value of a variable to a new variable, these things happen for 2 types above, let’s talk about Reference type first:

Cầu Vàng (Golden Bridge) in Da Nang, Vietnam
Class is a reference type in Swift

Classes are Reference types, then both of variables point to a memory allocation together. This is how reference type works while copying. Now take a look for Value type:

Struct is a value type in Swift
Struct is a value type in Swift

Structs are Value types then each variable will be allocated a specific memory cell. This is a biggest difference thing between reference & value types. Now, let’s talk about a specific value type: Array

Array is a value type in Swift
Array is a value type in Swift

Array is a Value type in Swift, but in this example, 2 variables point to a memory allocation like Reference type. Too confusing?? Let’s do something next:

After mutating array2 by appending a new element, finally it has been allocated by a new memory cell and still follow the Value type rule but “a little bit later”. This “a little bit later” called Copy-On-Write: Compiler only allocate a new memory allocation for a new variable if needed. This is a memory optimization tip on programming.

Unfortunately, Swift only support this Copy-On-Write for some kinds of value types such as: Array, Dictionary, Set, String … How about Struct? It’s a common value type we’re using and need to be applied this mechanism as well? Apple suggested us to implement a data structure named Ref & Box to support all value type:

Official implementation from Apple/Swift
Official implementation from Apple/Swift

You can find this official implementation from Apple/Swift: Advice: Use copy-on-write semantics for large values

By this suggestion, we can implement the Copy-On-Write for our Person struct above:

Implement Copy-On-Write for a struct
Implement Copy-On-Write for a struct

We have to wrap our struct inside another Box struct, it would be more boilerplate codes and not “Human-readable”. I have refactored this implementation by an open-source library named: CopyOnWriteSwift

You can install it easily via favorite dependency managers such as Cocoapods, Carthage & SwiftPackageManager. Now we can apply Copy-On-Write for any value types easier than ever just by an annotation: @CopyOnWrite

Implement Copy-On-Write for a struct by @CopyOnWrite
Implement Copy-On-Write for a struct by @CopyOnWrite

Conclusion: I hope Apple will apply Copy-On-Write mechanism for Structs by default in the future because nowadays we’re using Structs more frequently than Classes, particularly in Reactive Programming such as: SwiftUI + Combine or RxSwift + RxCocoa

--

--