2012-05-22 41 views
32

Khi lặp qua một mảng lớn với biểu thức phạm vi, tôi có nên sử dụng chức năng phạm vi tích hợp của Python hay số arange của numpy để có hiệu suất tốt nhất không?phạm vi tích hợp hoặc numpy.arange: hiệu quả hơn?

Lý luận của tôi cho đến nay:

arange lẽ phải viện đến một thực bản địa và có thể do đó nhanh hơn. Mặt khác, arange trả về một mảng đầy đủ, chiếm bộ nhớ, vì vậy có thể có một chi phí. Biểu thức phạm vi của Python 3 là một trình tạo, không chứa tất cả các giá trị trong bộ nhớ.

Trả lời

39

Đối với các mảng lớn có vón cục nên là giải pháp nhanh hơn.

Trong trường hợp khó khăn, bạn nên sử dụng kết hợp các phép tính được vectorized, ufuncsindexing để khắc phục sự cố khi chạy ở tốc độ C. Lặp qua các mảng có nhiều mảng không hiệu quả so với điều này.

(Một cái gì đó như là điều tồi tệ nhất bạn có thể làm sẽ là để lặp qua mảng với một chỉ số được tạo ra với range hoặc np.arange như câu đầu tiên trong câu hỏi của bạn gợi ý, nhưng tôi không chắc chắn nếu bạn thực sự có nghĩa là.)

import numpy as np 
import sys 

sys.version 
# out: '2.7.3rc2 (default, Mar 22 2012, 04:35:15) \n[GCC 4.6.3]' 
np.version.version 
# out: '1.6.2' 

size = int(1E6) 

%timeit for x in range(size): x ** 2 
# out: 10 loops, best of 3: 136 ms per loop 

%timeit for x in xrange(size): x ** 2 
# out: 10 loops, best of 3: 88.9 ms per loop 

# avoid this 
%timeit for x in np.arange(size): x ** 2 
#out: 1 loops, best of 3: 1.16 s per loop 

# use this 
%timeit np.arange(size) ** 2 
#out: 100 loops, best of 3: 19.5 ms per loop 

Vì vậy, trường hợp này nhanh hơn 4 lần so với sử dụng xrange nếu bạn làm đúng. Tùy thuộc vào vấn đề của bạn numpy có thể được nhanh hơn nhiều so với một 4 hoặc 5 lần tăng tốc độ.

Câu trả lời cho this question giải thích một số lợi thế khác của việc sử dụng mảng nhiều mảng thay vì danh sách python cho tập hợp dữ liệu lớn.

6

Trước hết, như được viết bởi @bmu, , bạn nên sử dụng kết hợp các phép tính được vector hóa, ufunc và lập chỉ mục. Thực tế có một số trường hợp yêu cầu lặp rõ ràng, nhưng những trường hợp này thực sự hiếm.

Nếu cần vòng lặp rõ ràng, với trăn 2.6 và 2.7, bạn nên sử dụng xrange (xem bên dưới). Từ những gì bạn nói, trong Python 3, phạm vi giống với xrange (trả về trình tạo). Vì vậy, có thể phạm vi là tốt cho bạn.

Bây giờ, bạn nên thử nó cho mình (sử dụng timeit: - ở đây ipython "ma thuật chức năng"):

%timeit for i in range(1000000): pass 
[out] 10 loops, best of 3: 63.6 ms per loop 

%timeit for i in np.arange(1000000): pass 
[out] 10 loops, best of 3: 158 ms per loop 

%timeit for i in xrange(1000000): pass 
[out] 10 loops, best of 3: 23.4 ms per loop 

Một lần nữa, như đã đề cập ở trên, hầu hết thời gian nó có thể sử dụng vector NumPy/mảng công thức (hoặc ufunc vv ...) chạy tốc độ ac: nhanh hơn nhiều. Đây là những gì chúng ta có thể gọi là "lập trình vector". Nó làm cho chương trình dễ thực hiện hơn C (và dễ đọc hơn) nhưng hầu như nhanh ở cuối.

+0

Cảm ơn, tôi không biết về chức năng ma thuật. – clstaudt

+3

Có một mô-đun python 'timeit' chuẩn cho phép thực hiện tương tự mà không có IPython. Nhưng nó dễ dàng hơn nhiều khi sử dụng chức năng ma thuật này. –

+0

-1 vì tôi nghĩ đây không phải là điểm chuẩn tốt. looping trên một mảng numpy là không hiệu quả. – bmu

Các vấn đề liên quan