2

セットと辞書で頻繁に使用されるクラスがあります。パフォーマンス上の理由から、このクラス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:)呼び出しが発生します。

私のコードでは、このようなオーバーヘッドは非常に高価であることが判明しました。誰かが回避策を知っていますか?

4

1 に答える 1