2016-06-13 14 views
6

私は公式の文書からこれらの例を得ました。 https://docs.python.org/2/library/timeit.htmlリストとジェネレータの理解速度(結合機能付き)

正確に最初の例(ジェネレータ式)が2番目(リストの理解度)より遅くなるのはなぜですか?

>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000) 
0.8187260627746582 
>>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000) 
0.7288308143615723 
+0

Ray Hettingerの答えはこちらhttp://stackoverflow.com/questions/9060653/list-comprehension-without-python –

+0

@BhargavRao - 私はRaymondの答えがこの問題に対処していることに同意しますが、この質問は基本的に_that_質問。 (ここで、OPはなぜlist-compがより速いのかを知りたがっています - 他の質問では、OPはジェネレータかlist-compの違いを知りませんでした...)。私は、このようなケースでデュープハンマーを下ろすための方針がどうあるべきかわからないと思っています。 – mgilson

+1

@mgilson他の質問は、この質問のスーパーセットです。私たちがより広範な質問の複製としてクローズすることができると述べたメタに関する記事がありました。例えば、閉じる*のように、これをリストの理解に変換するにはどうすればいいですか?*リストのcompとは何ですか? Opsを助けるための幅広い質問を作成する試みがあります([cannon](http://sopython.com/canon/)を見てください)。すべての場合、特定の質問が別の場所で回答されている場合、私たちは二重引用符として閉じます。 (私は通常の代わりにハンマーのための*正確なdupe *が答えを持っているという記述に反している) –

答えて

9

それがすでにリストやタプルではない場合str.join方法は、リストにその反復可能なパラメータに変換します。これにより、結合ロジックがアイテムに対して複数回反復することができます(結果文字列のサイズを計算するために1回通過し、実際にデータをコピーする2回目のパス)。

あなたはthe CPython source codeでこれを見ることができます:

PyObject * 
PyUnicode_Join(PyObject *separator, PyObject *seq) 
{ 
    /* lots of variable declarations at the start of the function omitted */ 

    fseq = PySequence_Fast(seq, "can only join an iterable"); 

    /* ... */ 
} 

C APIのPySequence_Fast機能は、私が説明しただけで何ありません。既にリストまたはタプルでない限り、任意のiterableをリストに変換します(基本的にはlistを呼び出して)。

ジェネレータの表現をリストに変換すると、ジェネレータの通常の利点(メモリのフットプリントが小さくなり、短絡の可能性があります)がstr.joinには適用されないため、発電機がその性能を悪化させている。

関連する問題