Skip to content

Commit b177c69

Browse files
committed
skip copying old values during removeAll()
As noted in FIXME(performance), calling `.removeAll(keepCapacity: true)` on a containter of type Dictionay or Set causes a copy of its storage being made. Only then, it would proceed to delete each element. This patch makes these hashed collections skip the wasteful copying step.
1 parent 2882816 commit b177c69

File tree

1 file changed

+11
-17
lines changed

1 file changed

+11
-17
lines changed

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3393,27 +3393,21 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType {
33933393
}
33943394
}
33953395

3396-
internal mutating func nativeRemoveAll() {
3397-
var nativeStorage = native
3398-
3399-
// FIXME(performance): if the storage is non-uniquely referenced, we
3400-
// shouldn’t be copying the elements into new storage and then immediately
3401-
// deleting the elements. We should detect that the storage is not uniquely
3402-
// referenced and allocate new empty storage of appropriate capacity.
3396+
internal mutating func nativeKeepCapacityRemoveAll() {
34033397

34043398
// We have already checked for the empty dictionary case, so we will always
34053399
// mutating the dictionary storage. Request unique storage.
3406-
let (reallocated, _) = ensureUniqueNativeStorage(nativeStorage.capacity)
3407-
if reallocated {
3408-
nativeStorage = native
3409-
}
34103400

3411-
for var b = 0; b != nativeStorage.capacity; ++b {
3412-
if nativeStorage.isInitializedEntry(b) {
3413-
nativeStorage.destroyEntryAt(b)
3401+
if !isUniquelyReferenced() {
3402+
self = .Native(NativeStorageOwner(minimumCapacity: native.capacity))
3403+
} else {
3404+
for b in 0..<native.capacity {
3405+
if native.isInitializedEntry(b) {
3406+
native.destroyEntryAt(b)
3407+
}
34143408
}
34153409
}
3416-
nativeStorage.count = 0
3410+
native.count = 0
34173411
}
34183412

34193413
internal mutating func removeAll(keepCapacity keepCapacity: Bool) {
@@ -3427,13 +3421,13 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType {
34273421
}
34283422

34293423
if _fastPath(guaranteedNative) {
3430-
nativeRemoveAll()
3424+
nativeKeepCapacityRemoveAll()
34313425
return
34323426
}
34333427

34343428
switch self {
34353429
case .Native:
3436-
nativeRemoveAll()
3430+
nativeKeepCapacityRemoveAll()
34373431
case .Cocoa(let cocoaStorage):
34383432
#if _runtime(_ObjC)
34393433
self = .Native(NativeStorage.Owner(minimumCapacity: cocoaStorage.count))

0 commit comments

Comments
 (0)