私は、クライアントIP:ポート、サーバーIP:ポートとキーワードが行内に存在するかどうかを確認するために、ループしている各行に対してかなり大きなテキストファイル(〜16k行) 2つのforループを使用して、if x in line
ステートメントをネストして、私が探している情報がその行に含まれているかどうかを確認します。ネストされたループのパフォーマンスが遅い
私が探している値を含む行を特定したら、sqlite DBを更新します。最初は、SQL UPDATE文が手動トランザクションでラップされていないため、実行にかなりの時間がかかりました。この変更を行った後、実行時間が大幅に改善されましたが、私はまだ以下のコードを完了するまでに数分かかりますが、私の恐ろしいループ構造が原因だと感じています。
誰でも以下のコードのスピードアップを支援するために、任意のパフォーマンスのヒントを持っていた場合、私は非常に感謝される:あなたのfor
ループの場合
c.execute("SELECT client_tuple, origin_tuple FROM connections")
# returns ~ 8k rows each with two items, clientIP:port and serverIP:port
tuples = c.fetchall()
with open('connection_details.txt', 'r') as f:
c.execute('BEGIN TRANSACTION')
# for each line in ~16k lines
for line in f:
# for each row returned from sql query
for tuple in tuples:
# if the client tuple (IP:Port) is in the line
if tuple[0] in line:
# if the origin tuple (IP:Port) is in the line
if tuple[1] in line:
# if 'foo' is in the line
if 'foo' in line:
# lookup some value and update SQL with the value found
bar_value = re.findall(r'(?<=bar\s).+?(?=\,)', line)
c.execute("UPDATE connections "
" SET bar = ? "
"WHERE client_tuple = ? AND origin_tuple = ?",
(bar_value[0], tuple[0], tuple[1]))
conn.commit()
変数名に 'tuple'を使うのは、組み込み関数なので避けてください。 – James
'fetchall()'のような行の例とタプルの例を投稿すると、私たちがあなたを助けてくれるでしょう。 +あなたが非常に高速なメンバシップテストを持っているので 'any()'、 'all()'、* sets *を調べたいかもしれません。 –
defitionによるネストループは遅いです。コードを微調整してもそれほど遠くには届きません。アルゴリズムを修正する必要があります。 – e4c5