由于结构实例是在堆栈上分配的,而类实例是在堆上分配的,因此结构有时会快得多。
但是,您应该始终自行衡量并根据您的独特用例做出决定。
考虑以下示例,该示例演示了使用struct 和class 包装Int 数据类型的两种策略。我使用 10 个重复值是为了更好地反映现实世界,你有多个字段。
class Int10Class {
let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int
init(_ val: Int) {
self.value1 = val
self.value2 = val
self.value3 = val
self.value4 = val
self.value5 = val
self.value6 = val
self.value7 = val
self.value8 = val
self.value9 = val
self.value10 = val
}
}
struct Int10Struct {
let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int
init(_ val: Int) {
self.value1 = val
self.value2 = val
self.value3 = val
self.value4 = val
self.value5 = val
self.value6 = val
self.value7 = val
self.value8 = val
self.value9 = val
self.value10 = val
}
}
func + (x: Int10Class, y: Int10Class) -> Int10Class {
return IntClass(x.value + y.value)
}
func + (x: Int10Struct, y: Int10Struct) -> Int10Struct {
return IntStruct(x.value + y.value)
}
性能衡量使用
// Measure Int10Class
measure("class (10 fields)") {
var x = Int10Class(0)
for _ in 1...10000000 {
x = x + Int10Class(1)
}
}
// Measure Int10Struct
measure("struct (10 fields)") {
var y = Int10Struct(0)
for _ in 1...10000000 {
y = y + Int10Struct(1)
}
}
func measure(name: String, @noescape block: () -> ()) {
let t0 = CACurrentMediaTime()
block()
let dt = CACurrentMediaTime() - t0
print("\(name) -> \(dt)")
}
代码可以在https://github.com/knguyen2708/StructVsClassPerformance找到
更新(2018 年 3 月 27 日):
从 Swift 4.0、Xcode 9.2 开始,在 iPhone 6S、iOS 11.2.6 上运行 Release build,Swift 编译器设置为 -O -whole-module-optimization:
-
class 版本耗时 2.06 秒
-
struct 版本耗时 4.17e-08 秒(快 50,000,000 倍)
(我不再平均多次运行,因为方差非常小,低于 5%)
注意:如果没有对整个模块进行优化,差异会小很多。如果有人能指出旗帜的实际作用,我会很高兴。
更新(2016 年 5 月 7 日):
从 Swift 2.2.1、Xcode 7.3 开始,在 iPhone 6S、iOS 9.3.1 上运行 Release build,平均运行 5 次以上,Swift 编译器设置为 -O -whole-module-optimization:
-
class 版本耗时 2.159942142s
-
struct 版本耗时 5.83E-08s(快 37,000,000 倍)
注意:正如有人提到的那样,在现实世界的场景中,结构中可能会有多个字段,我已经为结构/类添加了 10 个字段而不是 1 个字段的测试。令人惊讶的是,结果差别不大。
原始结果(2014 年 6 月 1 日):
(在结构/类上运行 1 个字段,而不是 10 个)
从 Swift 1.2、Xcode 6.3.2 开始,在 iPhone 5S、iOS 8.3 上运行 Release build,平均运行超过 5 次
-
class 版本耗时 9.788332333s
-
struct 版本耗时 0.010532942 秒(快 900 倍)
旧结果(来自未知时间)
(在结构/类上运行 1 个字段,而不是 10 个)
在我的 MacBook Pro 上发布版本:
-
class 版本耗时 1.10082 秒
-
struct 版本耗时 0.02324 秒(快 50 倍)