Swift 绝对不会吗< deep copy a large array, when one "guard let" the array?

问题描述 投票:0回答:1
typealias Stuff = [[String]] // typically zillions of items
var stuff: [String: Stuff] = [:] // tens of these

当我深度复制† a

Stuff
,

spare: Stuff = original{
    let line = $0.map{ $0 }
    return line
}

在新手机上需要 1/2 秒,所以当然要避免。

现在说我正在与

Stuff
一起工作,就像这样
calculations(on: "Cats")
,严格从
stuff["Cats"]

阅读
///Strictly reading from Stuff
func calculations(on: String) {
  guard stuff[on] != nil else { return }
  .. = stuff[on]!.blah.blah
  .. = stuff[on]!.blah.blah
  ..
  .. dozens and dozens of reads from stuff[on]!
}

当然如果你的话会更整洁

///Strictly reading from Stuff
func calculations(on: String) {
  guard let p = stuff[on] else { return }
  .. = p.blah.blah
  .. = p.blah.blah
  ..
  .. dozens and dozens of reads from p
}

如果我这样做,

  • 确实是不是深拷贝

    stuff["Cats"]
    吗?

  • 那真的可靠吗,而且绝对不会这样做?

作为一个相关问题,我相信,但我不确定,

这将是您检查

p
是否确实不是
stuff["Cats"]
->

的深层副本的方式
withUnsafePointer(to: &p[0][0]) {
    print("p is at \($0)")
}
withUnsafePointer(to: &stuff["Cats"][0][0]) {
    print("whereas stuff["Cats"][0][0] is at \($0)")
}

看起来不错吗?


顺便说一句,我真的不知道这是否是在 Swift 中深度复制 2D 字符串数组的最佳方法。

ios dictionary reference swift5 deep-copy
1个回答
0
投票

是的,保证不会创建数组存储的副本。

Array
具有写时复制行为:

与标准库中的所有可变大小集合一样,数组使用写时复制优化。阵列的多个副本共享相同的存储,直到您修改其中一个副本。

[...]

这意味着,如果一个数组与其他副本共享存储,则该数组上的第一个变异操作会产生复制该数组的成本。作为其存储的唯一所有者的数组可以就地执行变异操作。

虽然

let p = stuff[on]
stuff[on]
的值复制到
p
,但
Array
结构体的值很小 - 在我的机器上只有 8 个字节(参见
MemoryLayout<[[String]]>.size
)。

8 字节结构体值包含指向数组某个存储位置的指针,并且

p
stuff[on]
将指向相同的存储位置,如文档所述。

仅当您修改

stuff[on]
时,才会复制数组存储,例如添加另一个
[String]
p
stuff[on]
现在将指向不同的存储位置。但即便如此,inner 数组仍将共享存储,因为您没有修改内部数组。

© www.soinside.com 2019 - 2024. All rights reserved.