私は現在、Python辞書を使用しているときにパフォーマンスの問題を抱えています。私はいくつかの巨大なdicts(最大30kのエントリ)を持っている、と私はこれらのエントリの相互比較を行いたい。したがって、1つのエントリ(識別子がキー)が与えられた場合、このキーでこのエントリを含む他のディクテーションもいくつですか?現在、私のマシンでは最大5時間かかりますが、私のツールには数分で動作するはずです。私はすでに検索をより効率的にするためにエントリーを削除しようとしました。Python辞書の相互比較が遅すぎる、改善?
all_cached_data
は、これらのdictsのリストを持つリストです。 sources
には、all_cached_data
のリストに関する情報のリストがあります。
appearsin_list = []
# first, get all the cached data
sources = sp.get_sources()
all_cachedata = [0]*len(sources)
for source in sources:
iscached = source[8]
sourceid = int(source[0])
if iscached == "True":
cachedata, _ = get_local_storage_info(sourceid)
else:
cachedata = []
all_cachedata[sourceid-1] = cachedata
# second, compare cache entries
# iterate over all cached sources
for source in sources:
sourceid = int(source[0])
datatype = source[3]
iscached = source[8]
if verbose:
print("Started comparing entries from source " + str(sourceid) +
" with " + str(len(all_cachedata[sourceid-1])) + " entries.")
if iscached == "True":
# iterate over all other cache entries
for entry in all_cachedata[sourceid-1]:
# print("Comparing source " + str(sourceid) + " with source " + str(cmpsourceid) + ".")
appearsin = 0
for cmpsource in sources:
cmpsourceid = int(cmpsource[0])
cmpiscached = cmpsource[8]
# find entries for same potential threat
if cmpiscached == "True" and len(all_cachedata[cmpsourceid-1]) > 0 and cmpsourceid != sourceid:
for cmpentry in all_cachedata[cmpsourceid-1]:
if datatype in cmpentry:
if entry[datatype] == cmpentry[datatype]:
appearsin += 1
all_cachedata[cmpsourceid-1].remove(cmpentry)
break
appearsin_list.append(appearsin)
if appearsin > 0:
if verbose:
print(entry[datatype] + " appears also in " + str(appearsin) + " more source/s.")
all_cachedata[sourceid-1].remove(entry)
avg = float(sum(appearsin_list))/float(len(appearsin_list))
print ("Average appearance: " + str(avg))
print ("Median: " + str(numpy.median(numpy.array(appearsin_list))))
print ("Minimum: " + str(min(appearsin_list)))
print ("Maximum: " + str(max(appearsin_list)))
これをスピードアップするためのヒントについては、非常に感謝しています。
あなたはスクリプト言語で四重にネストされたループが30Kを扱うための良い方法だと思うどのような可能性が作られましたのデータですか? –
これはまさに私の問題です。私は悲しいことに、これは良いアプローチではないことを知っています。しかし、行列多項式として、これはそのままであるように思えます。高速ではなく、実際にはアルゴリズム的な方法では、増やすことはできません。だから私はそれに対処しなければならないし、もっと速いものがあるかもしれない。私はすでにnumpyについて考えましたが、私のデータをnumpy配列にマップする方法はわかりません。 – Lawlrenz
アルゴリズムを修正する必要があります。コードのどの部分が重要であり、どの部分が重要でないかは明確ではありません。 'cmpsource [8]'です。すべての用語を説明するのではなく、いくつかの単純なデータを使って、あなたが望むだけの仕組み、つまり比較と削除といういくつかの新しいコードを書いてください。 [mcve]の作成方法を参照してください。 –