[英]Does Swift have quadratic string concatenation when using var?
In the Swift Language Reference, under String Mutability it says: 在Swift语言参考中,在String Mutability下,它说:
You indicate whether a particular String can be modified (or mutated) by assigning it to a variable (in which case it can be modified), or to a constant (in which case it cannot be modified) 您可以通过将特定字符串分配给变量(在这种情况下可以对其进行修改)或常量(在这种情况下无法修改)来指示是否可以修改(或变异)特定字符串
It's unclear to me if the "it" that is mutable is the variable or the value . 我不清楚可变的“它”是变量还是值 。
For example, if I write: 例如,如果我写:
var s = ""
for i in 0...100 {
s += "a"
}
Is it akin to creating an NSMutableString
and calling appendString
100 times (ie linear cost)? 它类似于创建一个NSMutableString
并调用appendString
100次(即线性成本)?
Or is it akin to creating a series of ever-larger NSString
instances and combining them with stringByAppendingString
(ie quadratic cost)? 或者它类似于创建一系列更大的NSString
实例并将它们与stringByAppendingString
组合(即二次成本)?
Or perhaps it creates some kind of rope structure behind the scenes, so it's immutable and linear in aggregate? 或者它可能会在幕后创建某种绳索结构,因此它是不可变的和线性的聚合?
Appending to a collection like this (while String
is not itself a collection, you're essentially appending to its characters
view with that code) is linear, not quadratic. 附加到这样的集合(虽然String
本身不是一个集合,你实际上是用它代码附加到它的characters
视图)是线性的,而不是二次的。 A string in Swift has an internal buffer whose size is doubled whenever it fills up, which means you will see fewer and fewer reallocations as you repeatedly append. Swift中的一个字符串有一个内部缓冲区,当它填满时它的大小加倍,这意味着当你重复追加时,你会看到越来越少的重新分配。 The documentation describes appending in this way as an "amortized" O(1) operation: most of the time appending is O(1), but occasionally it will need to reallocate the string's storage. 该文档描述了以这种方式附加为“摊销”的O(1)操作:大多数时候附加的是O(1),但有时它需要重新分配字符串的存储。
Arrays, sets, and dictionaries have the same behavior, although you can also reserve a specific capacity for an array (using reserveCapacity(_:)
) if you know you'll be appending many times. 数组,集和词典具有相同的行为,但是如果您知道要多次追加,也可以为数组保留特定容量(使用reserveCapacity(_:)
)。
All these collections use "copy-on-write" to guarantee value semantics. 所有这些集合都使用“copy-on-write”来保证值语义。 Here, x
and y
share a buffer: 这里, x
和y
共享一个缓冲区:
let x = "a"
let y = x
If you mutate x
, it gets a new, unique copy of the buffer: 如果你改变x
,它会获得一个新的,唯一的缓冲区副本:
x += "b"
// x == "ab"
// y == "a"
After that, x
has its own buffer, so subsequent mutations won't require a copy. 之后, x
有自己的缓冲区,因此后续的突变不需要复制。
x += "c" // no copy unless buffer is full
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.