swift - 什么时候我的结构太大了?

标签 swift class struct heap-memory stack-memory

我们鼓励在 Swift 中使用 struct 而不是 class

这是因为

  1. 编译器可以做很多优化
  2. 实例是在堆栈上创建的,这比 malloc/free 调用性能更高

struct 变量的缺点是每次从函数返回或分配给函数时都会复制它们。显然,这也可能成为瓶颈。

例如想象一个 4x4 矩阵。每次分配/返回时都必须复制 16 个浮点值,这在 64 位系统上为 1'024 位。

避免这种情况的一种方法是在将变量传递给函数时使用 inout,这基本上是 Swifts 创建指针的方式。但是我们也不鼓励使用 inout

所以我的问题是:
我应该如何在 Swift 中处理大型、不可变的数据结构?
我是否需要担心创建一个包含许多成员的大型 struct
如果是,我什么时候越界?

最佳答案

这个被接受的答案并没有完全回答你的问题:Swift 总是复制结构。 Array/Dictionary/String/etc 所做的技巧是它们只是类的包装器(包含实际存储的属性)。这样 sizeof(Array) 就是指向该类的指针的大小 ( MemoryLayout<Array<String>>.stride == MemoryLayout<UnsafeRawPointer>.stride )

如果您有一个非常大的结构,您可能需要考虑将其存储的属性包装在一个类中以作为参数高效传递,并检查 isUniquelyReferenced在变异以提供 COW 语义之前。

结构还有其他效率优势:它们不需要引用计数,并且可以由优化器分解。

In Swift, values keep a unique copy of their data. There are several advantages to using value-types, like ensuring that values have independent state. When we copy values (the effect of assignment, initialization, and argument passing) the program will create a new copy of the value. For some large values these copies could be time consuming and hurt the performance of the program.

https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#the-cost-of-large-swift-values

还有关于容器类型的部分:

Keep in mind that there is a trade-off between using large value types and using reference types. In certain cases, the overhead of copying and moving around large value types will outweigh the cost of removing the bridging and retain/release overhead.

关于swift - 什么时候我的结构太大了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30560201/

相关文章:

c - 在 C 中读取字符时出现段错误

c++ - 在 C++ 中定义未命名结构时出错

swift - 本地 Vapor 项目的预检请求(选项)失败

c++ - 具有2个模板参数的C++类,具有1个参数的函数

ios - 同时旋转 2 个 UIPickerView

javascript - JavaScript 类实例是否克隆函数?

JavaScript 类设置自身

sql - Golang SQL 扫描结构奇怪

ios - 如何在 Swift 1.2 中从下到上为 UIlabel 设置动画

Swift - 从闭包中退出外部函数