arrays - 为什么 Swift 编译器会以 16 字节的倍数为基本类型的数组预分配空间? (64 位英特尔机器)

标签 arrays swift memory-management

我注意到在创建任何基本类型的数组时,给定 sizeof(..) <= 16 字节 (Bool, DoubleFloat 和一些 Int 类型已测试,见下文),然后 Swift 似乎总是默认以 16 字节的倍数预分配内存。此外,当使用 .reserveCapacity(..) 数组方法时;即使 8 字节的倍数就足够了,Swift 仍然以 16 字节的倍数分配空间。

问题: 出于好奇,Swift(编译器)这样做的原因是什么?或者它可能不是特别依赖于 Swift,而是 Swift 使用的编译器或我的处理器?


例子

默认:

/* Memory footprint */
sizeof(().dynamicType) // 0
sizeof(Bool) // 1
sizeof(Int16) // 2
sizeof(Int32) // 4
sizeof(Int64) // 8
sizeof(Float) // 4
sizeof(Double) // 8
sizeof(String) // 24 <-- for this, in multiples of 24 bytes, OK

/* Default pre-allocation in multiples of 16 bytes? */
let boolArr : [Bool] = [true]
let boolArrExact = [Bool](count: 16, repeatedValue: true)
let boolArrNext = [Bool](count: 17, repeatedValue: true)
let boolArrNextNext = [Bool](count: 33, repeatedValue: true)
boolArr.capacity // 16 elements <=> 16 bytes
boolArrExact.capacity // 16 elements <=> 16 bytes
boolArrNext.capacity // 32 elements <=> 32 bytes
boolArrNextNext.capacity // 48 elements <=> 48 bytes

let int16arr = [Int16](count: 1, repeatedValue: 1)
let int16arrExact = [Int16](count: 8, repeatedValue: 1)
let int16arrNext = [Int16](count: 9, repeatedValue: 1)
int16arr.capacity // 8 elements <=> 2*8 = 16 bytes
int16arrExact.capacity // 8 elements <=> 2*8 = 16 bytes
int16arrNext.capacity // 16 elements <=> 2*(2*8) = 32 bytes

let int64arr = [Int64](count: 1, repeatedValue: 1)
let int64arrNext = [Int64](count: 3, repeatedValue: 1)
int64arr.capacity // 2 elements <=> 8*2 = 16 bytes
int64arrNext.capacity // 4 elements <=> 2*(8*2) = 32 bytes

使用 .reserveCapacity(...) 的相同行为:

/* even when explicitly reserving capacity for less than default */
var boolArrCustomA : [Bool] = []
boolArrCustomA.reserveCapacity(5) // 8 bytes should suffice
boolArrCustomA.append(true)
boolArrCustomA.capacity // 16

var boolArrCustomB : [Bool] = []
boolArrCustomB.reserveCapacity(17) // 24 bytes should suffice
boolArrCustomB.append(true)
boolArrCustomB.capacity // 32

我在 64 位 Intel Core i5 机器上运行 Swift 2.1.1、XCode 7.2。


一些相关的线程,但是,并没有为我提供这个问题的答案:

最佳答案

MacOS X 和 iOS 上的所有分配都是通过 16 字节对齐完成的,不限于 Swift,多年来一直如此。这会带来一些速度提升,因为单个项目更有可能包含在单个缓存行中,如果使用矢量操作,速度会提高一些。它简化了分配和解除分配的算法。此外,它允许“标记指针对象”,因为任何指向对象的指针中的最后四位都保证为零。

关于arrays - 为什么 Swift 编译器会以 16 字节的倍数为基本类型的数组预分配空间? (64 位英特尔机器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34600971/

相关文章:

c# - 如果我在每个循环之间按 ENTER 键,为什么随机生成和数组会一起工作?

ruby-on-rails - Ruby 从数组中随机选择有时会重复返回相同的值

swift - 您可以在 SwiftUI 中直接将 Publisher 用作 @ObjectBinding 属性吗?

ios - 让 Button 标题标签大小根据 swift 中的设备(iPad 或 iPhone)

iphone - 将 ViewController 传递给 subview ,然后再次返回无法在 iOS 中释放 VC

objective-c - iOS 内存管理 - 说明

arrays - 排序数组并找到复杂度为 O(n) 的总和

java - 如何使此代码打印数组中的最高值?

ios - swift + 火力地堡 : randomly picking a group of objects using a query to the server

c++ - C++ 中的运行时内存分析