简体   繁体   中英

Swift MemoryLayout

I have a struct:

struct ShortResume {
    let age: Int32
    let hasVehicle: Bool
}

When I do print(MemoryLayout<ShortResume>.size) , it prints out 5, that is correct: Int32 occupies 4 bytes and Bool occupies 1 byte.

Then I change my struct to this:

struct ShortResume {
    let age: Int32?
    let hasVehicle: Bool
}

it prints out 6, that is also correct, because optional occupies 1 byte in memory.

However, when I change my struct to this:

struct ShortResume {
    let age: Int32?
    let hasVehicle: Bool?
}

it prints out 6 again, but it must be 7, because there are two optionals now.

Why? Maybe I'm missing something?

If you look at

MemoryLayout<Bool?>.size

You'll see that it is actually 1. But

MemoryLayout<Int32?>.size

is 5 as expected.

You may know that Optional is an enum declared like this:

public enum Optional<Wrapped> {
    case none
    case some(Wrapped)

    // ...
}

So the memory needed for a T? is the memory needed for T , plus one flag bit to store whether it is none or some . Therefore, one byte is theoretically more than necessary to store a Bool? .

And it turns out that Swift is actually really smart - in the current implementation, this flag can go in any unused place in the layout of T , which is why the flag and the value of the Bool are in the same byte.

These are some of my experiments:

struct A {
    let w: Bool
    let x: Int8
    let y: Int8
    let z: Int8
}

MemoryLayout<A?>.size // 4, that flag must be in the first byte

struct B {
    let w: Int8
    let x: Bool
    let y: Int8
    let z: Int8
}

MemoryLayout<B?>.size // 4, that flag must be in the second byte

struct C {
    let w: Int8
    let x: Int8
    let y: Bool
    let z: Int8
}

MemoryLayout<C?>.size // 4, that flag must be in the third byte

struct D {
    let w: Int8
    let x: Int8
    let y: Int8
    let z: Bool
}

MemoryLayout<D?>.size // 4, that flag must be in the last byte

struct E {
    let w: Int8
    let x: Int8
    let y: Int8
    let z: Int8
}

MemoryLayout<E?>.size // 5, that flag must be in the extra byte

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM