timeit
を使用して手動で実行しようとする代わりに、を使用したいくつかのパフォーマンス測定time
。
まず、Apple 2.7.2 64ビット:
In [37]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.05 s per loop
現在、python.org 3.3.0 64ビット:
In [83]: %timeit collections.deque((x for x in range(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.32 s per loop
In [84]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.31 s per loop
In [85]: %timeit collections.deque((x for x in iter(range(10000000)) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.33 s per loop
どうやら、3.xrange
は実際には2.xよりも少し遅いですxrange
。そして、OPのxrange
機能はそれとは何の関係もありません。(当然のことながら、__iter__
スロットへの1回限りの呼び出しは、ループ内で発生した10000000回の呼び出しの中で表示される可能性は低いですが、誰かが可能性としてそれを提示しました。)
しかし、それは30%遅いだけです。OPはどのようにして2倍遅くなりましたか?さて、32ビットPythonで同じテストを繰り返すと、1.58対3.12になります。したがって、これは、3.xが32ビットを損なう方法で64ビットパフォーマンス用に最適化されたもう1つのケースであると私は推測しています。
しかし、それは本当に重要ですか?3.3.0 64ビットでこれをもう一度チェックしてください:
In [86]: %timeit [x for x in range(10000000) if x%4 == 0]
1 loops, best of 3: 3.65 s per loop
したがって、ビルドにlist
は、反復全体の2倍以上の時間がかかります。
そして、「Python 2.6以降よりもはるかに多くのリソースを消費する」ということに関しては、私のテストから、3.xrange
は2.xとまったく同じサイズであるように見えます。xrange
また、10倍の大きさであっても、不要なリストを作成します。範囲の反復で実行できる問題の約10000000倍です。
for
そして、内部のCループの代わりに明示的なループはdeque
どうですか?
In [87]: def consume(x):
....: for i in x:
....: pass
In [88]: %timeit consume(x for x in range(10000000) if x%4 == 0)
1 loops, best of 3: 1.85 s per loop
for
したがって、ステートメントを繰り返す実際の作業とほぼ同じくらいの時間がステートメントで無駄になりrange
ます。
範囲オブジェクトの反復を最適化することを心配している場合は、おそらく間違った場所を探しています。
xrange
その間、同じことを何度言っても、なぜ削除されたのかと尋ね続けますが、もう一度繰り返します。削除されませんでした。名前がに変更されrange
、2.xrange
が削除されました。
3.3オブジェクトが2.xオブジェクトrange
の直接の子孫である(2.x関数の子孫ではない)ことのいくつかの証拠があります: 3.3および2.7へのソース。変更履歴も表示できます(ファイル内の任意の場所で文字列「xrange」の最後のインスタンスを置き換えた変更にリンクされていると思います)。xrange
range
range
xrange
それで、なぜそれは遅いのですか?
一つには、彼らは多くの新機能を追加しました。もう1つは、マイナーな副作用を伴うあらゆる種類の変更(特に反復内)を行ったことです。また、重要度の低いケースをわずかに悲観的にすることもありますが、さまざまな重要なケースを劇的に最適化するための多くの作業がありました。これをすべて合計すると、range
できるだけ速く反復するのが少し遅くなったのは驚きではありません。これは、誰も集中するほど重要ではないケースの1つです。このパフォーマンスの違いがコードのホットスポットである実際のユースケースは、誰も持っていない可能性があります。