この再帰をより効率的に書くことができますか?
-
10-12-2019 - |
質問
親が子をスポンサーしている場合、ノードが子であるツリーである階層組織があります。このコードでツリーをトラバースできるようです
def get_team(self, person, team):
firstline = User.query(User.sponsor == person.key).fetch(99999999)
if firstline:
for person in firstline:
team.append(person)
newdownline = self.downline(person, team)
return team
上記を使用すると、次の方法でユーザーの組織を取得できます
downline=user.get_team(user, [])
しかし、私は単一の要求に対してこれを何度もしなければならず、その多くの再帰が無効になる可能性があるので、より効率的な方法はありますか?または、ツリーを正しくトラバースできるため、コードは問題ありませんか?私の最初のバージョンでは、私は3つの変数を使用し、私はこれの代わりに2つの変数だけにコードを再配置できることがわかりました:
def downline(self, person, team, teamlist):
firstline = User.query(User.sponsor == person.key).fetch(99999999)
if firstline:
for person in firstline:
teamlist.append(person)
newdownline = self.downline(person, team, teamlist)
team.append(newdownline)
return teamlist
私はteamlist変数が本当に必要ではないことがわかったので、それを削除しました。私がやった方法は、最初に1つの変数が多すぎることでした:
people = user.downline(user, [], [])
解決
はい、計算上のトレードオフに応じて、より効率的な方法があります。
あなたは現在、あなたのツリーの深さ優先トラバーサル、完全に細かいアプローチを行っています。いくつかのRAM使用量を犠牲にして結果をキャッシュすることで、いくつかの速度を追加することができます:
if person.id in downline_cache:
team.append(downline_cache[person.id])
else:
downline_cache[person.id] = results
team.append(results)
ツリーがかなり小さい場合は、スレッドごとに1回、すべてを事前にキャッシュすることができます。これは、あなたがやっていることよりも多くのRAMを必要としますが、結果が何であるかを気にするたびに深さ優先トラバーサルを行うよりもはるかに速多くは、使用パターンと保存するデータの量に依存します。
キャッシュを使用する場合は、タイムアウトと"最終的に正しい"型保証を使用して、基になるデータの変更に対処する方法があることを確認する必要が