【问题标题】:Swift Dictionary: remove time complexitySwift Dictionary:消除时间复杂度
【发布时间】:2018-04-08 16:42:48
【问题描述】:

正如官方website 所说,在 Swift 中,从字典(或其他语言的映射)中按键删除是 O(n),这使得它的操作效率相当低。

如果 put() 和 get() 基于散列应该是 O(1),为什么不是 O(1)?

【问题讨论】:

  • 我的猜测是:由于字典的值语义,删除键值对可能需要复制数据,使其成为 O(N) 操作。
  • @MartinR 啊,是因为字典被实现为某种不可变(或堆栈)结构?
  • 是的,而且字典(以及 Set、Array、String...)使用写时复制策略来实现值语义,而无需不必要的副本。
  • 还要注意插入/删除/查找效率很大程度上取决于元素的哈希值。我不确定 Swift 是否保证任何这些操作的 O(1)。
  • This article 可能会有所启发

标签: swift time-complexity


【解决方案1】:

removeValue的源码为:

let (bucket, found) = asNative.find(key)
guard found else { return nil }
let isUnique = isUniquelyReferenced()
return asNative.uncheckedRemove(at: bucket, isUnique: isUnique).value

而 uncheckedRemove 的代码是:

_internalInvariant(hashTable.isOccupied(bucket))
let rehashed = ensureUnique(isUnique: isUnique, capacity: capacity)
_internalInvariant(!rehashed)
let oldKey = (_keys + bucket.offset).move()
let oldValue = (_values + bucket.offset).move()
_delete(at: bucket)
return (oldKey, oldValue)

而perseverUnique定义为:

if _fastPath(capacity <= self.capacity && isUnique) {
  return false
}
if isUnique {
  resize(capacity: capacity)
  return true
}
if capacity <= self.capacity {
  copy()
  return false
}
copyAndResize(capacity: capacity)
return true

虽然大多数操作将在 O(1) 上运行,但 ensureUnique func 可能有 O(n),如果项目不是唯一的,则 hashmap 将执行 copy(),这会花费 O(n) 时间复杂度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-13
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多