Swift5 写入时复制 copy-on-write

swift的数组是值类型,值类型的一个特点是在传递和赋值时进行复制。swift使用了copy-on-write来避免频繁复制带来的额外开销。只有当多个对象指向相同的资源,其中一个对象尝试修改资源内容时,copy才会触发。

维基百科描述很清晰

写入时复制(英语:Copy-on-write,简称COW)是一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(callers)同时请求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的(transparently)。此作法主要的优点是如果调用者没有修改该资源,就不会有副本(private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。

苹果关于数组使用copy-on-write的文档

Arrays, like all variable-size collections in the standard library, use copy-on-write optimization. Multiple copies of an array share the same storage until you modify one of the copies. When that happens, the array being modified replaces its storage with a uniquely owned copy of itself, which is then modified in place. Optimizations are sometimes applied that can reduce the amount of copying.
This means that if an array is sharing storage with other copies, the first mutating operation on that array incurs the cost of copying the array. An array that is the sole owner of its storage can perform mutating operations in place.

简单概述和演示:

// 打印对象的地址
func printPoint(name:String,point:UnsafePointer<Int>){
    print("\(name):\(point)")
}

var numberArray1 = [1, 2, 3, 4, 5]
var numberArray2 = numberArray1

printPoint(name: "numberArray1", point: numberArray1)
printPoint(name: "numberArray2", point: numberArray2)

numberArray2.append(6)

printPoint(name: "numberArray1", point: numberArray1)
printPoint(name: "numberArray2", point: numberArray2)

打印结果:
numberArray1:0x0000600000eb5560
numberArray2:0x0000600000eb5560
numberArray1:0x0000600000eb5560
numberArray2:0x00006000006b5750

可以看到,原本numberArray1numberArray2指向同一地址,当numberArray2要添加6时,触发了copy操作,把源地址0x0000600000eb5560的内容copy了一份到新地址0x00006000006b5750,然后在新地址上添加新元素6,赋值给numberArray2
最终numberArray1指向的地址没有改变,numberArray2指向新的地址

最后

虽然数组是值类型,但我们的赋值操作不会产生性能耗损,因为复制发生在有条件的内容改变时,而不是赋值的时候

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近遇到了以前的老同学。 我们大概有三年没有见面了,自从初中毕业之后,大家都去了不同的高中读书。当然,也有一些没有...
    渣渣号阅读 465评论 0 1
  • 最近搞了一个阿里云,准备部署下python2+python3的双环境。其实,阿里云上的ubuntu已经自带了pyt...
    Stansosleepy阅读 2,169评论 0 2
  • 一天,碧空如洗,万里无云,小明在公园里玩耍。忽然,小明听到树上传来小鸟叫声,好像在唱歌。小明喜欢极了,心想如果...
    约了嫦娥416阅读 373评论 0 1