セットと辞書で頻繁に使用されるクラスがあります。パフォーマンス上の理由から、このクラスHashable
は古い方法で実装し、計算されたハッシュをキャッシュします。
let hashValue: Int
init(...) {
self.hashValue = ...
}
Xcode 10.2 では、警告が表示されます。これhashValue
は非推奨であり、まもなくプロトコル要件ではなくなります。
私を悩ませているのは、hash(into:)
何も返さないため、計算されたハッシュをとにかくキャッシュする機能がないことです。
func hash(into hasher: inout Hasher) {
hasher.combine(...)
}
遊び場で次の例を考えてみましょう
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
次のログが表示されます
in hash
in hash
in hash
なぜ 2 つではなく 3 つの呼び出しが表示されるのかわかりませんが、=) を実行します。
したがって、同じインスタンスを辞書キーとして使用するか、このインスタンスをセットに追加するたびに、新しいhash(into:)
呼び出しが発生します。
私のコードでは、このようなオーバーヘッドは非常に高価であることが判明しました。誰かが回避策を知っていますか?