2011-07-16 6 views
2

私はスピード部門で苦しんでいるアプリケーションを微調整しようとしています。そのため、私はすべてのfor-loop文を可能な限りリスト内包に変換し始めました。Django QuerySetsを使っているときにforループの代わりにリスト内包を使用する

現在、私はDjangoクエリーセットの辞書を反復処理する必要がある関数に取り組んでいます。古いコードはfor-loopステートメントを使ってこれを反復処理し、正常に動作します。リストの理解を使用する私のコードは、私のモデルオブジェクトの代わりにdjango querysetsを返します。

def get_children(parent): 
    # The following works 
    children = [] 
    for value in get_data_map(parent).itervalues(): 
    children += list(value) 
    # This part doesn't work as intended. 
    booms = [value for value in get_data_map(parent).itervalues() if value] 
    import pdb 
    pdb.set_trace() 


(Pdb) type(children[0]) 
<class 'site.myapp.models.Children'> 

(Pdb) type(booms[0]) 
<class 'django.db.models.query.QuerySet'> 

注get_data_mapする値<class 'django.db.models.query.QuerySet'>

あるコードのこの部分は、アプリケーションの中で最も時間のかかる部分の一つである辞書を返すこと:ここで

コードがあります。これをリスト内包表記で処理すると、アプリケーションの速度はうまくいけば2倍速くなります。

コードのこの部分をどのように高速化できますか?

+1

あなたは、リスト内包が通常の 'for ... in ...'ループより速いと思いますか? – dcrosta

+1

私はジェネレータ、リスト内包表記、forループ、mapについて簡単なテストを行いました。リスト内包表記は.. forループよりも2倍ほど高速でした。 – mohi666

答えて

5

あなたの問題は、ループとリストの解説(より良いのはジェネレータ)ではありません。あなたの問題はデータベースへのクエリが多すぎますです。

1つのリストを取得しようとしているので、1つのクエリから取得しようとしているはずです。あなたの典型的なQuerySetに何があったのかを説明したならば、それらをマージする最良の方法を示すことができます。おそらくQオブジェクトにORマージを使用します。あるいは、一連の整数を積み上げて__in=フィルタに供給することもできます。

+0

これは解決できないと仮定し、OPが実際にリスト全体を使用していないと仮定すると、すべてのクエリセットが遅延評価のためにクエリを生成するわけではないため、itertools.chainはより高速になります。 – markijbema

+0

ええ、それほど情報が少ないので何をすべきかを言うのは本当に難しいです。しかし、私は、クエリのオーバーヘッドがDjangoのループオーバーヘッドよりもはるかに大きいことを発見しました。 –

2

クエリーセットのリストを作成しているため、ソリューションが機能しません。それぞれの値はクエリーセットであり、あなたはどこにも参加しません。比較:

a = [1,2,3] 
b = [x for x in a if x ] 

あなたはbも整数のリストであると思いますか?あなたはクエリーセット(親のリストよりも良い)のリストを取得しますが、あなたはまだそれらに加わる必要があります。あなたはitertools.chain使用して、この操作を行うことができます。

http://docs.python.org/library/itertools.html#itertools.chain

foos = itertools.chain(booms) 

FOOSはあなたが望むものでなければなりません。

1

は、それが正確に何が起こっているのか教えて厳しいです同意するが、Djangoのスピードの問題をデバッグすることはDjangoのデバッグツールバーを使用することにより大幅に容易になります。

https://github.com/django-debug-toolbar/django-debug-toolbar

問題は、あまりにも多くのデシベルのヒットであれば、見てツールバーの "SQLクエリ"タブ、それは非常にはっきりと表示されます。

関連する問題