当前位置:  开发笔记 > IOS > 正文

Swift数组和字典性能,removeAll()vs新实例

如何解决《Swift数组和字典性能,removeAll()vs新实例》经验,为你挑选了1个好方法。

我有一个数组(或字典),需要清除它.性能方面,是removeAll()创建新实例还是更好?

var things = [Thing]()

// Need to clear things
things.removeAll()
// or
things = [Thing]()

Kametrixom.. 24

(我不小心误读了你的问题并进行了查找Dictionary,见下文Array)

字典

thing = [String : Thing]()thing.removeAll()

既然Swift是开源的,我们可以看看这两个语句是否真的有所不同.

新的初始化

在挖掘源代码后,我在Dictionary 这里找到了一个初始化器:

public init() {
  self = Dictionary(minimumCapacity: 0)
}

/// Create a dictionary with at least the given number of
/// elements worth of storage.  The actual capacity will be the
/// smallest power of 2 that's >= `minimumCapacity`.
public init(minimumCapacity: Int) {
  _variantStorage =
    .Native(_NativeStorage.Owner(minimumCapacity: minimumCapacity))
}

正如您所看到的,底层存储是唯一的属性,在初始化时被分配.

移除所有

现在,让我们来看看removeAll()从这里:

  internal mutating func removeAll(keepCapacity keepCapacity: Bool) {
    if count == 0 {
      return
    }

    if !keepCapacity {
      self = .Native(NativeStorage.Owner(minimumCapacity: 2))
      return
    }

    if _fastPath(guaranteedNative) {
      nativeRemoveAll()
      return
    }

    switch self {
    case .Native:
      nativeRemoveAll()
    case .Cocoa(let cocoaStorage):
#if _runtime(_ObjC)
      self = .Native(NativeStorage.Owner(minimumCapacity: cocoaStorage.count))
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

在这里你可以看到条件!keepCapacity是真的,因为removeAll()removeAll(keepCapacity:)的默认参数是false.此代码来自存储枚举,因此它将自身替换为最小容量为2的新空存储.

结论

这两个陈述在理论上几乎完全相同,但我可以想象在实践中初始化可以被优化掉,因此它们完全相同.

排列

things = [Thing]() VS things.removeAll()

新的初始化

对于数组,这里更容易看到:

public init() {
  _buffer = _Buffer()
}

移除所有

看到这里:

public mutating func removeAll(keepCapacity keepCapacity: Bool = false) {
  if !keepCapacity {
    _buffer = _Buffer()
  }
  else {
    self.replaceRange(self.indices, with: EmptyCollection())
  }
}

与字典一样,_buffer是唯一的属性Array.

结论

同样Dictionary:两个语句在理论上几乎完全相同,但我可以想象在实践中初始化可以被优化掉,因此它们完全相同.



1> Kametrixom..:

(我不小心误读了你的问题并进行了查找Dictionary,见下文Array)

字典

thing = [String : Thing]()thing.removeAll()

既然Swift是开源的,我们可以看看这两个语句是否真的有所不同.

新的初始化

在挖掘源代码后,我在Dictionary 这里找到了一个初始化器:

public init() {
  self = Dictionary(minimumCapacity: 0)
}

/// Create a dictionary with at least the given number of
/// elements worth of storage.  The actual capacity will be the
/// smallest power of 2 that's >= `minimumCapacity`.
public init(minimumCapacity: Int) {
  _variantStorage =
    .Native(_NativeStorage.Owner(minimumCapacity: minimumCapacity))
}

正如您所看到的,底层存储是唯一的属性,在初始化时被分配.

移除所有

现在,让我们来看看removeAll()从这里:

  internal mutating func removeAll(keepCapacity keepCapacity: Bool) {
    if count == 0 {
      return
    }

    if !keepCapacity {
      self = .Native(NativeStorage.Owner(minimumCapacity: 2))
      return
    }

    if _fastPath(guaranteedNative) {
      nativeRemoveAll()
      return
    }

    switch self {
    case .Native:
      nativeRemoveAll()
    case .Cocoa(let cocoaStorage):
#if _runtime(_ObjC)
      self = .Native(NativeStorage.Owner(minimumCapacity: cocoaStorage.count))
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

在这里你可以看到条件!keepCapacity是真的,因为removeAll()removeAll(keepCapacity:)的默认参数是false.此代码来自存储枚举,因此它将自身替换为最小容量为2的新空存储.

结论

这两个陈述在理论上几乎完全相同,但我可以想象在实践中初始化可以被优化掉,因此它们完全相同.

排列

things = [Thing]() VS things.removeAll()

新的初始化

对于数组,这里更容易看到:

public init() {
  _buffer = _Buffer()
}

移除所有

看到这里:

public mutating func removeAll(keepCapacity keepCapacity: Bool = false) {
  if !keepCapacity {
    _buffer = _Buffer()
  }
  else {
    self.replaceRange(self.indices, with: EmptyCollection())
  }
}

与字典一样,_buffer是唯一的属性Array.

结论

同样Dictionary:两个语句在理论上几乎完全相同,但我可以想象在实践中初始化可以被优化掉,因此它们完全相同.


很好的完整答案,带有源代码来备份它
推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有