NSA*_*ict 6 struct class heap-memory stack-memory swift
我们鼓励在 Swift 中使用structover class。
这是因为
malloc/free调用性能要高得多变量的缺点struct是每次从函数返回或分配给函数时都会复制它们。显然,这也可能成为瓶颈。
例如,想象一个 4x4 矩阵。每次分配/返回时都必须复制 16 个浮点值,在 64 位系统上这将是 1'024 位。
避免这种情况的一种方法是inout在将变量传递给函数时使用,这基本上是 Swift 创建指针的方法。但我们也不鼓励使用inout.
所以我的问题是:
我应该如何在 Swift 中处理大型、不可变的数据结构?
我是否需要担心创建一个struct包含许多成员的大型项目?
如果是的话,我什么时候越界?
这个接受的答案并不能完全回答您的问题:Swift 总是复制结构。数组/字典/字符串/等的技巧是它们只是类的包装器(包含实际存储的属性)。这样 sizeof(Array) 只是指向该类的指针的大小 ( MemoryLayout<Array<String>>.stride == MemoryLayout<UnsafeRawPointer>.stride)
如果您有一个非常大的结构,您可能需要考虑将其存储的属性包装在一个类中,以便作为参数有效传递,并isUniquelyReferenced在变异之前进行检查以提供 COW 语义。
结构体还有其他效率优势:它们不需要引用计数并且可以由优化器分解。
在 Swift 中,值保留其数据的唯一副本。使用值类型有几个优点,例如确保值具有独立的状态。当我们复制值(赋值、初始化和参数传递的效果)时,程序将创建该值的新副本。对于某些较大的值,这些副本可能非常耗时并且会损害程序的性能。
https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#the-cost-of-large-swift-values
还有关于容器类型的部分:
请记住,使用大值类型和使用引用类型之间需要进行权衡。在某些情况下,复制和移动大值类型的开销将超过删除桥接和保留/释放开销的成本。