いくつかのパフォーマンス測定。を使用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.xはrange実際には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.x rangeは2.x xrangeとまったく同じサイズであるように見えます。さらに、10倍のサイズであっても、不要なリストを作成します。それでも、範囲の反復で何ができるかよりも約10000000x多い問題です。
そして、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.x rangeが削除されました。
3.3 rangeオブジェクトが2.x xrangeオブジェクトの直接の子孫であり(2.x range関数の子孫ではない)ことを証明するいくつかの例を次に示します:3.3rangeおよび2.7のxrangeソース。変更履歴も確認できます(ファイルの任意の場所にある文字列 "xrange"の最後のインスタンスを置き換えた変更にリンクされていると思います)。
では、なぜ遅いのでしょうか?
まあ、一つには、彼らは多くの新機能を追加しました。もう1つの理由として、彼らはあらゆる場所(特に反復の内部)であらゆる種類の変更を行っており、小さな副作用があります。そして、重要度の低いケースをわずかに悲観的にすることさえあるとしても、さまざまな重要なケースを劇的に最適化する多くの作業がありました。これをすべて足し合わせれば、rangeできるだけ速く反復することが少し遅くなったとしても驚くことではありません。これはそれほど重要ではないケースの1つであり、誰も集中するほど十分に気にすることはありません。このパフォーマンスの違いがコード内のホットスポットである実際のユースケースを誰も持つ可能性はほとんどありません。
rangePython 3.xではxrange、Python 2.xからのものです。range削除されたのは、実際にはPython 2.x でした。