Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Dictionary: remove time complexity

As stated by the official website, removing by key from a dictionary (or map, in other languages) is O(n) in Swift, making it a decently inefficient operation.

Why isn't it O(1) if put() and get() should be O(1) based on hashing?

enter image description here

like image 770
davidchuyaya Avatar asked Apr 08 '18 16:04

davidchuyaya


1 Answers

The source code of removeValue is:

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

While the uncheckedRemove's code is:

_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)

And the endureUnique is defined as:

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

While most operation will be run on O(1), the ensureUnique func may have O(n), if the item is not unique, the hashmap will do a copy(), which spends O(n) time complexity.

like image 172
vxst Avatar answered Jan 01 '23 19:01

vxst