[英]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.当我执行
print(MemoryLayout<ShortResume>.size)
时,它打印出 5,这是正确的:Int32 占用 4 个字节,Bool 占用 1 个字节。
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.它打印出 6,这也是正确的,因为 optional 在 memory 中占用 1 个字节。
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.它再次打印出 6,但它必须是 7,因为现在有两个可选项。
Why?为什么? Maybe I'm missing something?
也许我错过了什么?
If you look at如果你看
MemoryLayout<Bool?>.size
You'll see that it is actually 1. But你会看到它实际上是 1。但是
MemoryLayout<Int32?>.size
is 5 as expected.是 5 正如预期的那样。
You may know that Optional
is an enum declared like this:你可能知道
Optional
是一个这样声明的枚举:
public enum Optional<Wrapped> {
case none
case some(Wrapped)
// ...
}
So the memory needed for a T?
那么
T?
is the memory needed for T
, plus one flag bit to store whether it is none
or some
.是
T
所需的 memory ,加上一个标志位来存储它是none
还是some
。 Therefore, one byte is theoretically more than necessary to store a Bool?
因此,一个字节理论上比存储
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.事实证明,Swift 实际上非常聪明——在当前的实现中,这个标志可以 go 在
T
布局中任何未使用的位置,这就是标志和Bool
的值在同一个字节中的原因。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.