如何制作具有写时复制语义的容器? (Swift)
How can I make a container with copy-on-write semantics? (Swift)
我有一个非常大的结构,我想确保它不会被不必要地复制。我怎样才能为它制作一个写时复制容器?
写时复制通常是对某些支持对象的 struct
包装。
public final class MutableHeapStore<T>: NonObjectiveCBase
{
public typealias Storage = T
public private(set) var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
}
public struct COW<T>
{
public typealias Storage = MutableHeapStore<T>
public typealias Value = T
public var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
public var value: Value
{
get
{
return storage.storage
}
set
{
if isUniquelyReferenced(&storage)
{
storage.storage = newValue
}
else
{
storage = Storage(storage: newValue)
}
}
}
public init(_ value: Value)
{
self.init(storage: Storage(storage: value))
}
}
extension COW: CustomStringConvertible
{
public var description: String
{
return String(value)
}
}
诀窍在于每次盒装值发生变化时都断言 isUniquelyReferenced
。如果底层存储对象被单独引用,则什么也不做。但是,如果存在另一个引用,则必须创建一个新存储。
这段代码是线程安全的吗?它与任何其他值类型一样安全,例如Int
或 Bool
。
这里有一个更简单的例子。
struct COWExample1<T> {
private var box = Box<[T]>(value: [T]())
var count: Int {
return box.value.count
}
mutating func append(e: T) {
ensureBoxUniqueRefed()
box.value.append(e)
}
private mutating func ensureBoxUniqueRefed() {
if isUniquelyReferencedNonObjC(&box) == false {
box = box.duplicated()
}
}
}
private final class Box<T> {
var value: T
init(value: T) {
self.value = value
}
func duplicated() -> Box<T> {
return Box(value: value)
}
}
前面的回答都没有错,但是还有更简单的方法。 Swift 团队有 a list of performance tips,他们说:
The easiest way to implement copy-on-write is to compose existing copy-on-write data structures, such as Array.
没有比这更简单的了!
我有一个非常大的结构,我想确保它不会被不必要地复制。我怎样才能为它制作一个写时复制容器?
写时复制通常是对某些支持对象的 struct
包装。
public final class MutableHeapStore<T>: NonObjectiveCBase
{
public typealias Storage = T
public private(set) var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
}
public struct COW<T>
{
public typealias Storage = MutableHeapStore<T>
public typealias Value = T
public var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
public var value: Value
{
get
{
return storage.storage
}
set
{
if isUniquelyReferenced(&storage)
{
storage.storage = newValue
}
else
{
storage = Storage(storage: newValue)
}
}
}
public init(_ value: Value)
{
self.init(storage: Storage(storage: value))
}
}
extension COW: CustomStringConvertible
{
public var description: String
{
return String(value)
}
}
诀窍在于每次盒装值发生变化时都断言 isUniquelyReferenced
。如果底层存储对象被单独引用,则什么也不做。但是,如果存在另一个引用,则必须创建一个新存储。
这段代码是线程安全的吗?它与任何其他值类型一样安全,例如Int
或 Bool
。
这里有一个更简单的例子。
struct COWExample1<T> {
private var box = Box<[T]>(value: [T]())
var count: Int {
return box.value.count
}
mutating func append(e: T) {
ensureBoxUniqueRefed()
box.value.append(e)
}
private mutating func ensureBoxUniqueRefed() {
if isUniquelyReferencedNonObjC(&box) == false {
box = box.duplicated()
}
}
}
private final class Box<T> {
var value: T
init(value: T) {
self.value = value
}
func duplicated() -> Box<T> {
return Box(value: value)
}
}
前面的回答都没有错,但是还有更简单的方法。 Swift 团队有 a list of performance tips,他们说:
The easiest way to implement copy-on-write is to compose existing copy-on-write data structures, such as Array.
没有比这更简单的了!