Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Swift dictionary of indexed for performance? Even for exotic types (UUID)?

I want to construct some arrays that will remain in order to get fast searches. If I use something like this:

let dictionary: [Int:Int] = [:]
for i in 0 ..< 10000000 {
    dictionary[i] = 0
}

Would the query:

dictionary[n] == nil

be performed in logarithmic time?

If yes, is it the same for other types: Float, Double, String.

And finally, I need it to work with the UUID type, will it work?

like image 846
Nisba Avatar asked Dec 08 '16 22:12

Nisba


People also ask

Are dictionaries Equatable in Swift?

Without custom type in value of Dictionary, in Swift 2+ you can use the == operator to compare two Dictionary to check if they are equal or not. But in some cases with custom types as the Dictionary 's value (like struct ), you must adopt Equatable in order for that custom type to use == operator.

How does dictionary work in Swift?

Swift 4 dictionaries use unique identifier known as a key to store a value which later can be referenced and looked up through the same key. Unlike items in an array, items in a dictionary do not have a specified order. You can use a dictionary when you need to look up values based on their identifiers.

What are the differences between arrays and dictionaries in Swift?

Arrays are ordered collections of values. Sets are unordered collections of unique values. Dictionaries are unordered collections of key-value associations. Arrays, sets, and dictionaries in Swift are always clear about the types of values and keys that they can store.

Which type is defined for key in dictionary in Swift?

The Key type of the dictionary is Int , and the Value type of the dictionary is String . To create a dictionary with no key-value pairs, use an empty dictionary literal ( [:] ). var emptyDict: [String: String] = [:]


2 Answers

Swift's Dictionary is implemented with a hash table, therefore lookups will typically be done in O(1) time, assuming a good hashing algorithm. As @rmaddy says, this therefore means that the type of key is mainly irrelevant – the only thing that really matters is whether it has a good implementation of hashValue, which you shouldn't have to worry about at all for standard library types.

The worst case time complexity for a hash table lookup (assuming maximal hash collisions) depends on how the hash table resolves the collisions. In the case of Dictionary, two storage schemes can be used, native or Cocoa.

From HashedCollections.swift.gyb:

In normal usage, you can expect the backing storage of a Dictionary to be a NativeStorage.

[...]

Native storage is a hash table with open addressing and linear probing. The bucket array forms a logical ring (e.g., a chain can wrap around the end of buckets array to the beginning of it).

Therefore the worst case lookup time complexity is O(n), as if each element has the same hash, potentially every element will have to be searched through in order to determine if a given element exists in the table.

For Cocoa storage, a _CocoaDictionaryBuffer wrapper is used in order to wrap an NSDictionary. Unfortunately, I cannot find any documentation on how it's implemented, although it's Core Foundation counterpart CFDictionary's header file states that:

The access time for a value in the dictionary is guaranteed to be at worst O(lg N) for any implementation, current and future

(Which sounds like it uses a balanced binary tree in order to handle collisions.)

like image 182
Hamish Avatar answered Sep 27 '22 20:09

Hamish


Dictinaries and arrays are different. You talk about arrays, but your code is using dictionaries. You could set up an array of optional Int values and use code like what you propose.

With your existing code, you're looking up a key/value pair from a dictionary. Dictinaries use hashes to do lookups, and I believe dictionary lookups are done in constant time, although I was unable to confirm that after a quick search.

EDIT:

Check this link:

https://www.raywenderlich.com/123100/collection-data-structures-swift-2

That says that both arrays and dictinaries can be as bad as O(n•log(n)) performance, but typically give O(1).

like image 32
Duncan C Avatar answered Sep 27 '22 19:09

Duncan C