Beberapa pengukuran kinerja, menggunakan timeitalih-alih mencoba melakukannya secara manual time.
Pertama, Apple 2.7.2 64-bit:
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
Sekarang, python.org 3.3.0 64-bit:
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
Rupanya, 3.x rangebenar-benar sedikit lebih lambat dari 2.x xrange. Dan fungsi OP xrangetidak ada hubungannya dengan itu. (Tidak mengherankan, karena panggilan satu kali ke __iter__slot tidak akan terlihat di antara 10.000.000 panggilan untuk apa pun yang terjadi dalam loop, tetapi seseorang mengemukakannya sebagai suatu kemungkinan.)
Tapi ini hanya 30% lebih lambat. Bagaimana OP mendapat 2x lebih lambat? Nah, jika saya mengulangi tes yang sama dengan Python 32-bit, saya mendapatkan 1,58 vs 3,12. Jadi tebakan saya adalah bahwa ini adalah kasus lain di mana 3.x telah dioptimalkan untuk kinerja 64-bit dengan cara yang menyakitkan 32-bit.
Tetapi apakah itu benar-benar penting? Lihat ini, dengan 3.3.0 64-bit lagi:
In [86]: %timeit [x for x in range(10000000) if x%4 == 0]
1 loops, best of 3: 3.65 s per loop
Jadi, membangun listmembutuhkan lebih dari dua kali lebih lama dari seluruh iterasi.
Dan untuk "menghabiskan lebih banyak sumber daya daripada Python 2.6+", dari pengujian saya, sepertinya 3.x rangepersis ukuran yang sama dengan 2.x xrange—dan, bahkan jika itu 10x lebih besar, membangun daftar yang tidak perlu masih sekitar 10.000.000x lebih dari masalah daripada apa pun rentang iterasi mungkin bisa dilakukan.
Dan bagaimana dengan forloop eksplisit, bukan loop C di dalam 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
Jadi, hampir sebanyak waktu yang terbuang dalam forpernyataan seperti pada pekerjaan aktual iterasi range.
Jika Anda khawatir tentang mengoptimalkan iterasi objek rentang, Anda mungkin mencari di tempat yang salah.
Sementara itu, Anda terus bertanya mengapa xrangedihapus, tidak peduli berapa kali orang mengatakan hal yang sama kepada Anda, tetapi saya akan mengulanginya lagi: Tidak dihapus: diubah namanya menjadi range, dan 2.x rangeadalah yang dihapus.
Berikut beberapa bukti bahwa rangeobjek 3.3 adalah turunan langsung dari xrangeobjek 2.x (dan bukan dari rangefungsi 2.x ): sumber ke 3.3range dan 2.7xrange . Anda bahkan dapat melihat riwayat perubahan (terkait dengan, saya percaya, perubahan yang menggantikan instance terakhir dari string "xrange" di mana saja dalam file).
Jadi, mengapa lebih lambat?
Pertama, mereka telah menambahkan banyak fitur baru. Untuk yang lain, mereka telah melakukan semua jenis perubahan di semua tempat (terutama di dalam iterasi) yang memiliki efek samping kecil. Dan ada banyak pekerjaan untuk secara dramatis mengoptimalkan berbagai kasus penting, bahkan jika kadang-kadang sedikit pesimis kasus yang kurang penting. Tambahkan semua ini, dan saya tidak terkejut bahwa iterasi rangesecepat mungkin sekarang sedikit lebih lambat. Ini adalah salah satu dari kasus-kasus yang kurang penting yang tidak akan pernah dipedulikan oleh siapa pun. Tidak ada yang mungkin memiliki kasus penggunaan nyata di mana perbedaan kinerja ini adalah hotspot dalam kode mereka.
rangedalam Python 3.x berasalxrangedari Python 2.x. Sebenarnya Python 2.xrangeyang dihapus.