Быстродействие массива и словаря Swift, removeAll () vs new instance
У меня есть массив (или словарь), и мне нужно его очистить. С точки зрения производительности, лучше ли removeAll() или создать новый экземпляр?
var things = [Thing]()
// Need to clear things
things.removeAll()
// or
things = [Thing]()
1 ответ:
(я случайно неправильно понял ваш вопрос и посмотрел его для
Dictionary, см. ниже дляArray)Словарь
Теперь, когда Swift является открытым исходным кодом, мы можем посмотреть, действительно ли эти два утверждения делают что-то другое.
thing = [String : Thing]()vs.thing.removeAll()Новая инициализация
Покопавшись в источнике, я нашел инициализатор для a
Dictionaryздесь :public init() { self = Dictionary<Key, Value>(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
Теперь давайте посмотрим на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]()vsthings.removeAll()Новая инициализация
Для массива еще проще увидеть здесь :
public init() { _buffer = _Buffer() }RemoveAll
Смотрите здесь :
public mutating func removeAll(keepCapacity keepCapacity: Bool = false) { if !keepCapacity { _buffer = _Buffer() } else { self.replaceRange(self.indices, with: EmptyCollection()) } }Как и в случае со словарем,
_bufferявляется единственным свойствомArray.Заключение
То же самое, что и для
Dictionary: оба утверждения делают практически то же самое в теории, но я могу себе представить, что на практике инициализация может быть оптимизирована, так что они делают точно то же самое.
Comments