Một số phép đo hiệu suất, sử dụng timeitthay vì cố gắng thực hiện bằng tay time.
Đầu tiên, 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
Bây giờ, 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
Rõ ràng, 3.x rangethực sự là chậm hơn so với 2.x một chút xrange. Và xrangechức năng của OP không có gì để làm với nó. (Không có gì đáng ngạc nhiên, vì một cuộc gọi một lần đến __iter__vị trí không có khả năng hiển thị trong số 10000000 cuộc gọi đến bất kỳ điều gì xảy ra trong vòng lặp, nhưng ai đó đã đưa ra như một khả năng.)
Nhưng nó chỉ chậm hơn 30%. Làm thế nào mà OP có được gấp 2 lần chậm? Chà, nếu tôi lặp lại các bài kiểm tra tương tự với Python 32 bit, tôi nhận được 1,58 so với 3,12. Vì vậy, tôi đoán rằng đây là một trường hợp khác trong đó 3.x đã được tối ưu hóa cho hiệu suất 64 bit theo cách làm tổn thương 32 bit.
Nhưng nó thực sự quan trọng? Hãy xem điều này, với 3.3.0 64 bit một lần nữa:
In [86]: %timeit [x for x in range(10000000) if x%4 == 0]
1 loops, best of 3: 3.65 s per loop
Vì vậy, việc xây dựng listmất nhiều hơn gấp đôi so với toàn bộ lần lặp.
Và đối với "tiêu thụ nhiều tài nguyên hơn Python 2.6+", từ các thử nghiệm của tôi, có vẻ như 3.x rangecó kích thước chính xác như 2.x xrange, và ngay cả khi nó lớn gấp 10 lần, xây dựng danh sách không cần thiết vẫn còn khoảng 10000000x vấn đề hơn bất cứ điều gì mà phép lặp phạm vi có thể làm.
Và những gì về một forvòng lặp rõ ràng thay vì vòng lặp C bên trong 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
Vì vậy, gần như lãng phí thời gian trong fortuyên bố như trong công việc thực tế của việc lặp lại range.
Nếu bạn lo lắng về việc tối ưu hóa việc lặp lại của một đối tượng phạm vi, có lẽ bạn đang tìm sai chỗ.
Trong khi đó, bạn cứ hỏi tại sao lại xrangebị xóa, bất kể mọi người nói với bạn điều tương tự bao nhiêu lần, nhưng tôi sẽ nhắc lại lần nữa: Nó không bị xóa: nó được đổi tên thành rangevà 2.x rangelà những gì đã bị xóa.
Dưới đây là một số bằng chứng cho thấy rangeđối tượng 3.3 là hậu duệ trực tiếp của xrangeđối tượng 2.x (chứ không phải của rangechức năng 2.x ): nguồn tới 3.3range và 2.7xrange . Bạn thậm chí có thể thấy lịch sử thay đổi (tôi tin rằng, sự thay đổi đã thay thế phiên bản cuối cùng của chuỗi "xrange" ở bất kỳ đâu trong tệp).
Vì vậy, tại sao nó chậm hơn?
Chà, trước tiên, họ đã thêm rất nhiều tính năng mới. Mặt khác, họ đã thực hiện tất cả các loại thay đổi ở mọi nơi (đặc biệt là trong vòng lặp) có tác dụng phụ nhỏ. Và đã có rất nhiều công việc để tối ưu hóa đáng kể các trường hợp quan trọng khác nhau, ngay cả khi đôi khi nó hơi bi quan những trường hợp ít quan trọng hơn. Thêm tất cả điều này lên, và tôi không ngạc nhiên rằng việc lặp lại rangecàng nhanh càng tốt bây giờ chậm hơn một chút. Đó là một trong những trường hợp ít quan trọng mà không ai quan tâm đủ để tập trung vào. Không ai có thể có trường hợp sử dụng thực tế trong đó sự khác biệt hiệu suất này là điểm nóng trong mã của họ.
rangetrong Python 3.x làxrangetừ Python 2.x. Trên thực tế, Python 2.xrangeđã bị xóa.