【发布时间】:2018-05-16 02:47:22
【问题描述】:
对于 Swift 编程(截至 2018 年 5 月,Swift 4.1,Xcode 9.3)的普遍共识是结构应该是首选,除非您的逻辑明确要求对对象的共享引用。
众所周知,结构体的一个问题是它们是按值传递的,因此当您将结构体传递到函数或从函数返回时会生成副本。如果您有一个大型结构(例如其中包含 12 个属性),那么这种复制可能会很昂贵。
这通常被人们辩护说 swift 编译器和/或 LLVM 可以省略副本(即传递对结构的引用,而不是复制它)并且只需要在您实际改变结构时进行复制。
这一切都很好,但总是在理论上谈论它 - “作为一种优化,LLVM可以删除副本”之类的东西。
我的问题是,谁能告诉我们实际上发生了什么? 是否编译器实际上会删除副本,或者它只是一种理论上可能存在的未来优化? (例如,C# 编译器理论上也可以删除结构副本,但它实际上从未这样做过,Microsoft 建议您不要将结构用于大于 16 字节的内容 [1])
如果 swift 确实删除了结构副本,是否有一些解释或启发式来说明它是否以及何时这样做?
注意:我说的是用户定义的结构,而不是像数组和字典这样的标准库中内置的东西
[1]https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct
【问题讨论】:
-
当您在这里指的是 C++ 术语时,我将指出 C++ 副本有可能比 Swift 副本大几个数量级。在 C++ 中复制一个向量 10,000 个重要对象的成本将使复制一个具有 12 个属性的“大型结构”的成本相形见绌。
-
编译器还可以专门化接受值类型参数的函数,以便只传递函数体中使用的属性,比较stackoverflow.com/q/43486408/2976878
标签: swift swift-structs