3

関数の結果をキャッシュするためのキャッシュ キーを生成するメソッドを作成しています。キーは、関数名とパラメーターのハッシュ値の組み合わせに基づいています。

現在、hashlib を使用してシリアル化されたバージョンのパラメーターをハッシュしていますが、大きなオブジェクトをシリアル化するには操作に非常にコストがかかるため、代替手段は何ですか?

#get the cache key for storage
def cache_get_key(*args):
    import hashlib
    serialise = []
    for arg in args:
        serialise.append(str(arg))
    key = hashlib.md5("".join(serialise)).hexdigest()
    return key

更新: hash(str(args)) を使用してみましたが、args に比較的大きなデータが含まれている場合でも、ハッシュ値の計算に時間がかかります。それを行うより良い方法はありますか?

実際、大きなデータを持つ str(args) は永遠にかかります...

4

5 に答える 5

1

hash関数だけを使ってみましたか?タプルでは完全にうまく機能します。

于 2012-04-10T21:58:11.040 に答える
1

オブジェクトを作成し、それが小さなコンポーネント (バイナリ BLOB ではない) で構成されていると仮定すると、サブコンポーネントのハッシュを使用してオブジェクトを作成するときにハッシュを事前計算できます。

たとえば、ではなくserialize(repr(arg))arg.precomputedHash if isinstance(arg, ...) else serialize(repr(arg))

独自のオブジェクトを作成したり、使用可能hashなオブジェクトを使用したりしない場合は、オブジェクトを変更しないと仮定して、オブジェクト参照 -> ハッシュのメモ化テーブルを保持できます。最悪の場合、メモ化を可能にする関数型言語を使用できます。そのような言語のすべてのオブジェクトはおそらく不変であり、したがってハッシュ可能であるためです。

于 2012-04-10T22:03:11.633 に答える
1
def cache_get_key(*args):
    return hash(str(args))

または(本当にhashlibライブラリを使用したい場合)

def cache_get_key(*args):
    return hashlib.md5(str(args)).hexdigest()

配列を文字列にするためにコードを書き直す必要はありません。内蔵のものを使用してください。

代替ソリューション

以下は@8bitwideが提案する解決策です。このソリューションでは、ハッシュはまったく必要ありません!

def foo(x, y):
    return x+y+1

result1 = foo(1,1)
result2 = foo(2,3)

results = {}
results[foo] = {}
results[foo][ [1,1] ] = result1
results[foo][ [2,3] ] = result2
于 2012-04-10T22:05:14.637 に答える
0

任意の python オブジェクトを random.seed() にフィードし、random.random() から返された最初の値を「ハッシュ」値として使用する人を見てきました。値の素晴らしい分布は得られませんが (歪む可能性があります)、任意のオブジェクトに対しては機能するようです。

暗号強度のハッシュが必要ない場合は、ブルーム フィルターで使用する整数のリスト用のハッシュ関数のペアを考え出しました。それらは以下に表示されます。ブルーム フィルターは、実際にはこれら 2 つのハッシュ関数の線形結合を使用して、任意の数のハッシュ関数を取得しますが、適切な分布で少し散乱するだけでよい他のコンテキストではうまく機能するはずです。それらは、線形合同乱数生成に関するクヌースの著作に触発されています。それらは整数のリストを入力として受け取ります。これは、シリアル化された文字の ord() である可能性があると思います。

MERSENNES1 = [ 2 ** x - 1 for x in [ 17, 31, 127 ] ]
MERSENNES2 = [ 2 ** x - 1 for x in [ 19, 67, 257 ] ]


def simple_hash(int_list, prime1, prime2, prime3):
    '''Compute a hash value from a list of integers and 3 primes'''
    result = 0
    for integer in int_list:
        result += ((result + integer + prime1) * prime2) % prime3
    return result


def hash1(int_list):
    '''Basic hash function #1'''
    return simple_hash(int_list, MERSENNES1[0], MERSENNES1[1], MERSENNES1[2])


def hash2(int_list):
    '''Basic hash function #2'''
    return simple_hash(int_list, MERSENNES2[0], MERSENNES2[1], MERSENNES2[2])
于 2012-04-10T22:43:21.800 に答える