2011-12-05 34 views
25

Tôi vừa thay đổi một chương trình mà tôi đang viết để giữ dữ liệu của mình dưới dạng các mảng cứng nhắc khi tôi gặp sự cố về hiệu suất và sự khác biệt thật đáng kinh ngạc. Ban đầu nó mất 30 phút để chạy và bây giờ mất 2,5 giây!Tại sao mảng NumPy quá nhanh?

Tôi đã tự hỏi nó như thế nào. Tôi giả sử đó là bởi vì nó loại bỏ sự cần thiết cho các vòng lặp for nhưng ngoài ra tôi đang bối rối.

+4

Tôi đoán đó là do các mảng bị lỗi được thực hiện trong C thay vì bằng Python. –

+7

@NoufalIbrahim: Danh sách Python cũng được [triển khai trong C] (http://stackoverflow.com/questions/3917574/how-is-pythons-list-implemented/3958322#3958322). –

+7

Câu hỏi khá mơ hồ mà không có bất kỳ dấu hiệu nào về hai chương trình khác nhau đang hoạt động và cách chúng được thực hiện. –

Trả lời

52

Mảng nhiều mảng là các mảng được đóng gói dày đặc của loại đồng nhất. Ngược lại, các danh sách Python là các mảng con trỏ tới các đối tượng, ngay cả khi tất cả chúng đều có cùng kiểu. Vì vậy, bạn nhận được những lợi ích của locality of reference.

Ngoài ra, nhiều thao tác Numpy được triển khai trong C, tránh chi phí chung của vòng lặp trong Python, kiểm tra con trỏ và kiểm tra loại động từng yếu tố. Tốc độ tăng phụ thuộc vào các hoạt động bạn đang thực hiện, nhưng một vài đơn đặt hàng của cường độ không phải là hiếm trong chương trình crunching số.

+1

Làm thế nào để có thể cung cấp tiền tố Python cho các hoạt động C-viết này? Kỹ thuật này được đặt tên là gì? –

+0

Điều này không đúng. Các danh sách Python không phải là các mảng của các con trỏ khi các phần tử là các kiểu nguyên thủy, như các số nguyên. Một cách nhanh chóng để kiểm tra đó là lưu một số vào một biến và tạo thành một mảng với biến đó trong đó. Nếu bạn thay đổi biến, mảng không thay đổi. – Rohan

+0

@Rohan Hãy nhớ rằng các kiểu nguyên thủy là các đối tượng. Vì vậy, khi bạn thêm biến đó vào danh sách, bạn thực sự chỉ cần thêm đối tượng mà biến cụ thể trỏ vào danh sách. Trong trường hợp này, đối tượng này là một số. Vì vậy, khi bạn thay đổi biến, hoặc chính xác hơn, hãy đổi tên thành một số nguyên mới, bạn không thay đổi các thuộc tính của đối tượng gốc, tức là số gốc. Do đó, người ta hy vọng rằng số 'tương ứng' trong mảng không thay đổi giá trị của nó. – Kun

1

Các mảng nặng nề tương tự như các mảng 'bình thường' như các mảng trong c. Lưu ý rằng mọi phần tử phải cùng loại. Tăng tốc là rất tốt vì bạn có thể tận dụng khả năng tìm nạp trước và bạn có thể truy cập ngay lập tức bất kỳ phần tử nào trong mảng bằng chỉ mục của nó.

+0

Bạn có thể giải thích về cách có cùng loại cho mỗi phần tử giúp tính toán nhanh hơn không? – Rohan

9

mảng có nhiều mảng là cấu trúc dữ liệu chuyên biệt. Điều này có nghĩa là bạn không chỉ nhận được những lợi ích của việc biểu diễn hiệu quả trong bộ nhớ, mà còn thực hiện các triển khai chuyên biệt hiệu quả.

Ví dụ: nếu bạn đang tổng hợp hai mảng, việc bổ sung sẽ được thực hiện với các hoạt động vector CPU chuyên biệt, thay vì gọi việc triển khai thực hiện python của int trong một vòng lặp.

+1

Những (hoạt động chuyên môn và tối ưu hóa động) là câu trả lời đúng.Các yếu tố nhỏ như tìm nạp trước và địa phương tham chiếu chỉ trở nên quan trọng sau khi các yếu tố hiệu suất chính (thông dịch viên trên không) được giải quyết. – Dave

+2

địa phương tham chiếu là quan trọng vì hai lý do: vì bản thân địa phương (và các hiệu ứng của nó trên bộ nhớ đệm) và do thiếu hướng dẫn có nghĩa là các hướng dẫn xử lý gián đoạn có thể bị bỏ qua. –

1

Bạn vẫn có vòng lặp, nhưng chúng được thực hiện bằng c. Numpy dựa trên Atlas, là một thư viện cho các hoạt động đại số tuyến tính.

http://math-atlas.sourceforge.net/

Khi đối mặt với một tính toán lớn, nó sẽ chạy thử nghiệm sử dụng một số triển khai để tìm hiểu đó là một trong những nhanh nhất trên máy tính của chúng tôi tại thời điểm này. Với một số thuật toán xây dựng khó khăn có thể được song song trên nhiều cpus. Vì vậy, bạn sẽ có tối ưu hóa cao c chạy trên khối bộ nhớ liên tục.

+5

Numpy không dựa trên Atlas. Nó có thể sử dụng, nếu có, thực thi BLAS cho một tập con rất nhỏ của chức năng của nó (về cơ bản là dấu chấm, gemv và gemm). BLAS đó có thể là BLAS tham chiếu được tích hợp sẵn, hoặc Atlas hoặc Intel MKL (phân phối enthought được xây dựng với điều này). – talonmies

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