I have a class being heavily used in Sets and Dictionaries.
For performance reasons this class implements Hashable
in a old way and caches the computed hash:
let hashValue: Int
init(...) {
self.hashValue = ...
}
In Xcode 10.2 I see a warning, that hashValue
is deprected and will stop being a protocol requirement soon.
What bothers me is a lack of ability to cache the computed hash anyhow, because hash(into:)
does not return anything.
func hash(into hasher: inout Hasher) {
hasher.combine(...)
}
Consider the following example in a playground
class Class: Hashable {
let param: Int
init(param: Int) {
self.param = param
}
static func ==(lhs: Class, rhs: Class) -> Bool {
return lhs.param == rhs.param
}
public func hash(into hasher: inout Hasher) {
print("in hash")
hasher.combine(param)
}
}
var dict = [Class: Int]()
let instance = Class(param: 1)
dict[instance] = 1
dict[instance] = 2
You will see the following logs
in hash
in hash
in hash
I have no idea, why we see 3 calls instead of 2, but we do =).
So, every time you use a same instance as a dictionary key or add this instance into a set, you get a new hash(into:)
call.
In my code such an overhead turned out to be very expensive. Does anyone know a workaround?