如何证明" copy-on-write"在Swift中的String类型

时间:2017-10-14 17:26:57

标签: swift string copy-on-write

正如标题所说,我试图证明自己,Swift中的String支持COW(写入时复制)。但我找不到证据。在尝试以下代码后,我在Array和Dictionary上证明了COW:

func address(of object: UnsafeRawPointer) -> String {
    let addr = Int(bitPattern: object)
    return String(format: "%p", addr)
}

var xArray = [20, 30, 40, 50, 60]
var yArray = xArray

// These two addresses were the same
address(of: xArray) 
address(of: yArray)

yArray[0] = 200
// The address of yArray got changed
address(of: yArray)

但是对于String类型,它不起作用。

var xString = "Hello World"
var yString = xString

// These two addresses were different
address(of: xString)
address(of: yString)

我从官方的Swift代码库中抛弃了测试函数。

func _rawIdentifier(s: String) -> (UInt, UInt) {
    let tripe = unsafeBitCast(s, to: (UInt, UInt, UInt).self)
    let minusCount = (tripe.0, tripe.2)
    return minusCount
}

但是这个函数似乎只是将指向的实际值转换为不是地址。因此,具有相同值的两个不同的String变量将具有相同的rawIdentifier。仍然无法向我证明COW。

var xString = "Hello World"
var yString = "Hello" + " World" 

// These two rawIdentifiers were the same
_rawIdentifier(s: xString)
_rawIdentifier(s: yString)

那么COW如何处理Swift中的String类型?

1 个答案:

答案 0 :(得分:4)

编译器仅为两者创建单个存储 "Hello World""Hello" + " World"

您可以通过检查汇编代码来验证 从

获得
swiftc -emit-assembly cow.swift

仅定义单个字符串文字

    .section    __TEXT,__cstring,cstring_literals
L___unnamed_1:
    .asciz  "Hello World"

一旦字符串发生变异,字符串存储的地址就会立即生效 缓冲区(第一个成员"魔法"元组,实际上是_baseAddress struct _StringCore中定义的var xString = "Hello World" var yString = "Hello" + " World" print(_rawIdentifier(s: xString)) // (4300325536, 0) print(_rawIdentifier(s: yString)) // (4300325536, 0) yString.append("!") print(_rawIdentifier(s: yString)) // (4322384560, 4322384528) 更改:

func address(of object: UnsafeRawPointer) -> String

为什么你的

xArray

函数显示yArrayxString的相同值,但是 不适用于yStringUnsafePointer<T>

数组传递给带有不安全指针的函数传递 第一个数组元素的地址,两者相同 数组如果共享存储空间。

字符串传递给采用不安全指针的函数传递 指向字符串的临时 UTF-8表示的指针。 即使对于相同的字符串,该地址在每次调用中也可能不同。

这种行为记录在&#34;使用Swift with Cocoa和 目标C&#34;参考UnsafeRawPointer参数,但显然 {{1}}参数的工作方式相同。