说
struct Teste: Codable {
let a: Int
lazy var x: Int = {
print("I just changed this Teste item")
return a + 1000
}()
}
你呢
var hugeData: [Teste] // 750 million of these
所以它有点像来自云端的数据,保存在单例或类似物中。
那么你碰巧
let see: [Teste] = hugeData.filter{ .. }
// 4 of these. we'll say one of them happens to be hugeData[109333072]
也许在视图或类似的东西中显示。下一步!虽然see
存在,但你碰巧出于某种原因
let width = hugeData[109333072].x
那一刻,它必须复制-写入所有内容hugeData
,只是因为see
那时存在一点点愚蠢的内容。
- 或者可能是 Swift 的写时复制机制足够智能,在这种情况下,可以真正在微小的块上执行写时复制?有人知道是否是这种情况吗?
我刚刚才意识到,如果处理大量数据的话,如果原始大数组中发生了一些变化,而恰好存在一些微不足道的写时复制数组,那么这将带来巨大的性能损失。
(并且/或者,正如要点中提到的那样,也许 Swift 通过对小对象进行实际的复制来解决这个问题??)
简而言之,如果对数组进行了更改而恰好存在副本,那么将写时复制应用于(所有)“原始”数组是否正确?
这是一个简短的、不言自明的演示...
struct Teste: Codable {
let a: Int
lazy var x: Int = {
print("I just calculated it", a + 1000)
return a + 1000
}()
}
print("yo")
tt = [Teste(a:7), Teste(a:8), Teste(a:9)]
let tt2 = tt.filter{ $0.a > 8 }
print(tt)
print(tt2)
print("yes, still nil in tt2")
print("go..", tt[2].x)
print("go again..", tt[2].x)
print(tt)
print(tt2)
print("yes, copy on write was? applied to the original huge array")
print("ie YES, still nil in tt2")
let tt3 = tt.filter{ $0.a > 8 }
print(tt)
print(tt3)
print("yes, the set value seems to carry through to tt3")
结果
yo
[.Teste(a: 7, $__lazy_storage_$_x: nil), .Teste(a: 8, $__lazy_storage_$_x: nil), .Teste(a: 9, $__lazy_storage_$_x: nil)]
[.Teste(a: 9, $__lazy_storage_$_x: nil)]
yes, still nil in tt2
I just calculated it 1009
go.. 1009
go again.. 1009
[.Teste(a: 7, $__lazy_storage_$_x: nil), .Teste(a: 8, $__lazy_storage_$_x: nil), .Teste(a: 9, $__lazy_storage_$_x: Optional(1009))]
[.Teste(a: 9, $__lazy_storage_$_x: nil)]
yes, copy on write was? applied to the original huge array
ie YES, still nil in tt2
[.Teste(a: 7, $__lazy_storage_$_x: nil), .Teste(a: 8, $__lazy_storage_$_x: nil), .Teste(a: 9, $__lazy_storage_$_x: Optional(1009))]
[.Teste(a: 9, $__lazy_storage_$_x: Optional(1009))]
yes, the set value seems to carry through to tt3
那么在这种情况下它会复制 7.5 亿个项目数组吗?