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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With