DevPrep

All topics › Modern Swift

What is an existential container (any P)? Why is any costlier than T: P?

Senior PRO

The idea

any P is a value whose type is unknown at compile time, so the compiler packs it into a fixed-size existential container:

In total any P takes 40 bytes. If the value fits the buffer it is stored inline; if not, it is allocated on the heap and the buffer holds a reference (boxing). A class instance always fits: it is one reference. For a class-bound protocol (any P & AnyObject) the container is shorter: reference + witness table, 16 bytes; metadata comes from the object.

protocol P {}
struct Small: P { var a, b, c: Int }        // 24 bytes — fits the buffer
struct Big: P { var a, b, c, d: Int }       // 32 bytes — heap (boxing)
final class Obj: P {}

print(MemoryLayout<Small>.size, MemoryLayout<Big>.size)   // 24 32
print(MemoryLayout<any P>.size)                            // 40
print(MemoryLayout<any P & AnyObject>.size)                // 16

let values: [any P] = [
    Small(a: 1, b: 2, c: 3), Big(a: 1, b: 2, c: 3, d: 4), Obj()
]

The rest of this answer, with code and interview follow-ups, is in the DevPrep app.

Read the full answer in DevPrep

Practice this before your interview

DevPrep turns these answers into one-minute challenges: what does this code print, find the bug, mock interviews. One challenge a day.

Get DevPrep on the App Store