2010-07-17 37 views
9

Tôi đang học python gần đây và đang thực hiện nhiều thao tác với ngôn ngữ.Trong python, tại sao đọc từ một mảng chậm hơn so với đọc từ danh sách?

Một điều tôi thấy thú vị là, khi tôi đọc từ một mảng, nó gần như một nửa thời gian chậm hơn so với danh sách. Có ai biết tại sao không?

đây là mã của tôi:

 
from timeit import Timer 
import array 

t = 10000 
l = range(t) 
a = array.array('i', l) 
def LIST(): 
    for i in xrange(t): 
     l[i] 

def ARRAY(): 
    for i in xrange(t): 
     a[i] 

print Timer(LIST).timeit(1000); 
print Timer(ARRAY).timeit(1000); 

đầu ra là:

 
0.813191890717 
1.16269612312 

mà chỉ ra rằng đọc mảng là chậm hơn so với danh sách. Tôi nghĩ mảng là bộ nhớ có kích thước cố định, trong khi danh sách là cấu trúc động. Vì vậy, tôi giả định rằng mảng sẽ nhanh hơn danh sách.

Có ai có bất kỳ lời giải thích nào không?

+1

có thể dupe/answer: http://stackoverflow.com/questions/176011/python-list-vs-array-when-to-use - Về cơ bản array.array là một trình bao bọc xung quanh một mảng C vì vậy tôi nghĩ rằng có trên không khi truy cập nó. Không sử dụng nó cho toán học. –

+0

Cố gắng đoán hiệu quả Python thứ hai - đặc biệt đối với những người đến từ nền giống như C - thường phản trực giác. Trước tiên hãy viết mã, sau đó tối ưu hóa nếu bạn đo lường vấn đề hiệu suất; điều này cũng áp dụng cho C, nhưng vì các yếu tố ngôn ngữ rất gần với máy mà mọi người thường quên. – msw

+1

Đối với toán học bạn có thể muốn sử dụng gọn gàng (không có sẵn cho python 3 chưa), chỉ có thần biết tại sao numpy không phải là thư viện chuẩn. –

Trả lời

8

Cần có thời gian để bọc một số nguyên vào một số int của Python.

+2

Khá như vậy. Hàm LIST chỉ cần tăng và sau đó giảm số lượng tham chiếu cho từng phần tử danh sách. Mặt khác, hàm ARRAY phải phân bổ bộ nhớ cho mỗi số nguyên (trừ các số nguyên nhỏ hơn có tối ưu hóa) và sau đó giải phóng nó một lần nữa. – Duncan

1

Danh sách Python thực sự giống với một số cách mảng thông thường, chúng không phải là danh sách Lisp, nhưng chúng có thể truy cập ngẫu nhiên nhanh.

8

list s là "vectơ tăng trưởng năng động" (rất giống với C++ 's std::vector, nói) nhưng điều đó không có cách nào làm chậm truy cập ngẫu nhiên đối với họ (họ không liên kết danh sách -!). Các mục của danh sách là các tham chiếu đến các đối tượng Python (các mục): truy cập vào một yêu cầu (trong CPython) tăng số lượng tham chiếu của mục (trong các triển khai khác, dựa trên bộ sưu tập rác cao cấp hơn, thậm chí không phải ;-). Các mục của Array là các bit và byte thô: truy cập vào một yêu cầu một đối tượng Python mới được tổng hợp dựa trên giá trị nhị phân đó. Ví dụ:

$ python -mtimeit -s'import array; c=array.array("B", "bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0903 usec per loop 
$ python -mtimeit -s'c=list("bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0601 usec per loop 

30 giây thêm giây để truy cập không có vẻ quá xấu ;-).

Ngoài ra, lưu ý rằng timeit là tốt hơn để sử dụng từ dòng lệnh - tự động lựa chọn lặp lại, đơn vị đo lường được hiển thị cho thời gian, v.v. Đó là cách tôi luôn sử dụng nó (nhập mô-đun được mã hóa tùy chỉnh với các chức năng được gọi, nếu cần - nhưng ở đây không cần phải có) - đó là vì vậy nhiều handier hơn là nhập và sử dụng nó từ một mô-đun!

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