in-line vs out-of-line (mutable) storage in swift
Generated on 8/8/2024
1 search
In Swift, the distinction between in-line and out-of-line (mutable) storage has significant performance implications. Here's a summary based on the "Explore Swift performance" session from WWDC 2024:
In-line Storage
- Structs, Tuples, and Enums: These types use in-line storage, meaning everything they contain is laid out in-line within their container, typically in the order it was declared. This avoids allocating memory on the heap, which can be beneficial for small types.
- Performance: In-line storage can be more efficient for small types because it avoids the overhead of heap allocation. However, for larger types, the cost of copying can become significant, as each copy requires duplicating all stored properties.
Out-of-line Storage
- Classes and Actors: These types use out-of-line storage, where everything they contain is laid out in-line within an object, and the container stores a pointer to that object. This means that copying a class value involves copying the ownership of the reference, which just means retaining the object it refers to.
- Performance: Out-of-line storage can be more memory efficient for larger types, as each copy refers to the same object, thus reusing memory. However, it comes with the overhead of reference counting and potential heap allocation.
Combining Both
- Copy-on-Write: One way to get both out-of-line storage and value semantics is to wrap the class in a struct and use copy-on-write. This technique is used in Swift's fundamental data structures like
Array
,Dictionary
, andString
.
For more detailed information, you can refer to the following segments from the session:
- Explore Swift performance (13:34): Discusses how Swift handles memory layout and allocation when the compiler doesn't statically know the representation of a type.
- Explore Swift performance (12:31): Explains how class types use out-of-line storage and how to achieve out-of-line storage with value semantics using copy-on-write.
- Explore Swift performance (11:30): Discusses the trade-offs between in-line and out-of-line storage, including the performance implications of copying large structs.
Session Chapter Markers
- 0 = Introduction
- 84 = Agenda
- 106 = What is performance?
- 271 = Low-level principles
- 276 = Function calls
- 509 = Memory allocation
- 634 = Memory layout
- 837 = Value copying
- 1254 = Putting it together
- 1268 = Dynamically-sized types
- 1473 = Async functions
- 1691 = Closures
- 1836 = Generics
- 2040 = Wrap up