Understanding Swift Copy-on-Write mechanisms

Luciano Almeida
Nov 19, 2017 · 3 min read

In Swift, we have reference types(Classes) and value types (Structs, Tuples, enums). The value types have a copy semantic. That means if you assign a value type to a variable or pass it as a parameter to a function(unless it is an inout parameter), the underlying data of this value is going to be copied. You will have two values with the same content but, allocated in two distinct memory addresses. For a more detailed explanation about the difference between reference and value types on Apple’s Blog.

Since we are going to talk about Copy-on-Write, is very important to understand the Swift value semantics.

So … Let’s start

What is this Copy-on-Write?

Image for post
Image for post

In Swift when you have large value type and have to assign or pass as a parameter to a function, copying it can be really expensive in terms of performance because you'll have to copy all the underlying data to another place in memory.

Trying to minimize the issue, the Swift Standard library implements this set of mechanisms for some value types such as Array, where the value will be copied only upon mutation, and even then, only if it has more than one reference to it, because if this value is uniquely referenced, it doesn’t need to copy, it can be just mutated on the reference. So, just assign to a variable or pass an Array to a function doesn’t necessarily means it’ll be copied and that really improve the performance.

Copy-on-Write is not a default behavior of value types, is something that is implemented on the Swift Standard Library for certain types such as Array and Collections. So, it means that not every value type in the Standard Library has this behavior. Also, the value types that you create doesn’t have it, unless you implement it yourself. This is something I’ll talk about later in the next section.

Let's see in practice how works with an example:

This is a simple way to show how Copy-on-Write works. Basically creating the array1 with values and assign to array2, where because of Copy-on-Write it isn’t being copied so both point to the same address. So the array2 data is being copied only when we mutate it as you can see on lines 15–17.

Implementing Copy-on-Write behavior for your custom value types

You can implement Copy-on-Write behavior yourself to take advantage of this with your custom value types. The example below can be found on OptimizationTips.rst in the Swift main repo.

It’s a sample code showing how you use a reference type to implement copy-on-write for a generic value type T. Basically, it’s a wrapper that manages the reference type and just returns a new instance if the value is not uniquely referenced. Otherwise, it just mutates the value of the reference type.

Conclusion

Copy-on-Write is a very intelligent way to optimize copy of value types and that is a mechanism heavily used in Swift, even though most of the times we don’t see it explicitly because fortunately, it’s implementation is done for us on the Standard Library. But is definitely something good to know so we can do our daily code implementations in a way that take full advantage of this.

Image for post
Image for post

That’s all for this article, hope you like it

If you got some comment or question, please let me know. I will be really happy in receiving your feedback.

Thanks for reading :)

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store