1. ホーム
  2. python

numpy配列のハッシュ化で最も効率的なプロパティ

2023-09-14 10:29:23

質問

を格納できるようにする必要があります。 numpy array の中に dict をキャッシュのために使用します。 ハッシュスピードは重要です。

array はインディケータを表します。したがって、オブジェクトの実際のアイデンティティは重要ではありませんが、値は重要です。 現在の値だけに興味があるので、変異性は気になりません。

に格納するために、何をハッシュ化すればよいのでしょうか? dict ?

私の現在のアプローチは str(arr.data) よりも高速な md5 よりも高速です。


相対的な時間の見当をつけるために、回答からいくつかの例を取り入れました。

In [121]: %timeit hash(str(y))
10000 loops, best of 3: 68.7 us per loop

In [122]: %timeit hash(y.tostring())
1000000 loops, best of 3: 383 ns per loop

In [123]: %timeit hash(str(y.data))
1000000 loops, best of 3: 543 ns per loop

In [124]: %timeit y.flags.writeable = False ; hash(y.data)
1000000 loops, best of 3: 1.15 us per loop

In [125]: %timeit hash((b*y).sum())
100000 loops, best of 3: 8.12 us per loop

この特定のユースケース(インジケータの小さな配列)には、次のように見えるでしょう。 arr.tostring は最高のパフォーマンスを提供します。

読み取り専用バッファのハッシュはそれ自体で高速ですが、書き込み可能フラグを設定するオーバーヘッドにより、実際には遅くなります。

どのように解決するのですか?

読み取り専用にすれば、基盤となるバッファを単純にハッシュ化することができます。

>>> a = random.randint(10, 100, 100000)
>>> a.flags.writeable = False
>>> %timeit hash(a.data)
100 loops, best of 3: 2.01 ms per loop
>>> %timeit hash(a.tostring())
100 loops, best of 3: 2.28 ms per loop

非常に大きなアレイの場合 hash(str(a)) は非常に高速ですが、その場合は配列のごく一部しか考慮されません。

>>> %timeit hash(str(a))
10000 loops, best of 3: 55.5 us per loop
>>> str(a)
'[63 30 33 ..., 96 25 60]'