知识卡片

写时复制让值语义摆脱性能负担

专业/工作 · 752.c

内容

如果值类型每次赋值都真的复制一份完整数据,大数组这类结构的赋值开销会高到不可接受。Swift标准库的值类型(如Array)用”写时复制”(COW)解决这个矛盾:结构体内部只持有一个指向真正数据的引用类型缓冲区,赋值时复制的只是这个引用,多个实例暂时共享同一份底层存储;只有当某个实例真正要修改数据时,才在修改前检查这份存储是否仅被自己引用(isKnownUniquelyReferenced),如果被多个实例共享,才在这一刻真正复制一份独立数据再修改。这样一来,只读场景下值类型和引用类型一样零拷贝开销,只有真正出现分歧写入时才付出复制成本——值语义的”直觉正确性”和引用语义的”性能”被同时保住了,Swift没有在语言层面直接提供COW,需要时得自己按这个模式手写mutating方法配合内部引用类型缓冲区实现。

参考来源

《Swift编程权威指南》第18章《值类型与引用类型》