2013-07-30 44 views
11

a few articles cho thấy MATLAB thích hoạt động cột hơn hoạt động hàng và tùy thuộc vào việc bạn đặt dữ liệu của mình hiệu suất can vary significantly. Điều này rõ ràng là vì MATLAB sử dụng thứ tự column-major để biểu diễn mảng.Hiệu suất của hoạt động hàng và cột trong NumPy

Tôi nhớ đọc rằng Python (NumPy) sử dụng đơn đặt hàng row-major. Với câu hỏi này, câu hỏi của tôi là:

  1. Ai có thể mong đợi sự khác biệt về hiệu suất khi làm việc với NumPy?
  2. Nếu câu trả lời cho câu hỏi trên là có, thì một số ví dụ là ví dụ nào làm nổi bật sự khác biệt này?
+0

Bạn có thể muốn xem [this] (http://stackoverflow.com/questions/17840661). Đây là một ví dụ gần đây, nơi có sự khác biệt lớn trong các hoạt động trên các trục khác nhau. Mặc dù điều này có thể là một lỗi. – Daniel

Trả lời

11

Giống như nhiều điểm chuẩn, điều này thực sự phụ thuộc vào đặc điểm của tình huống. Đúng là, theo mặc định, tạo ra các mảng theo thứ tự tiếp giáp (C-hàng liền kề) C, vì vậy, trong phần tóm tắt, các hoạt động quét qua các cột phải nhanh hơn các phép quét qua các hàng. Tuy nhiên, hình dạng của mảng, hiệu suất của ALU và bộ đệm ẩn bên dưới trên bộ xử lý có tác động rất lớn đến các chi tiết cụ thể.

Ví dụ, trên MacBook Pro của tôi, với một số nguyên nhỏ hoặc nổi mảng, thời gian cũng tương tự, nhưng một loại số nguyên nhỏ là chậm hơn so với các loại phao đáng kể:

>>> x = numpy.ones((100, 100), dtype=numpy.uint8) 
>>> %timeit x.sum(axis=0) 
10000 loops, best of 3: 40.6 us per loop 
>>> %timeit x.sum(axis=1) 
10000 loops, best of 3: 36.1 us per loop 

>>> x = numpy.ones((100, 100), dtype=numpy.float64) 
>>> %timeit x.sum(axis=0) 
10000 loops, best of 3: 28.8 us per loop 
>>> %timeit x.sum(axis=1) 
10000 loops, best of 3: 28.8 us per loop 

Với mảng lớn tuyệt đối sự khác biệt trở nên lớn hơn, nhưng ít nhất là trên máy tính của tôi vẫn còn nhỏ hơn cho các kiểu dữ liệu lớn hơn:

>>> x = numpy.ones((1000, 1000), dtype=numpy.uint8) 
>>> %timeit x.sum(axis=0) 
100 loops, best of 3: 2.36 ms per loop 
>>> %timeit x.sum(axis=1) 
1000 loops, best of 3: 1.9 ms per loop 

>>> x = numpy.ones((1000, 1000), dtype=numpy.float64) 
>>> %timeit x.sum(axis=0) 
100 loops, best of 3: 2.04 ms per loop 
>>> %timeit x.sum(axis=1) 
1000 loops, best of 3: 1.89 ms per loop 

Bạn có thể nói numPy để tạo ra một mảng (cột chính) Fortran tiếp giáp sử dụng lập luận order='F' từ khóa để numpy.asarray, numpy.ones, numpy.zeros và các loại tương tự hoặc bằng cách chuyển đổi mảng hiện có bằng cách sử dụng numpy.asfortranarray. Như dự kiến, đơn đặt hàng này hoán đổi hiệu quả của các hoạt động hàng hoặc cột:

in [10]: y = numpy.asfortranarray(x) 
in [11]: %timeit y.sum(axis=0) 
1000 loops, best of 3: 1.89 ms per loop 
in [12]: %timeit y.sum(axis=1) 
100 loops, best of 3: 2.01 ms per loop 
0

Tôi nghi ngờ điều này sẽ khác nhau tùy thuộc vào dữ liệu và hoạt động.

Câu trả lời dễ là viết một số bài kiểm tra sử dụng cùng một thế giới thực, dữ liệu sắp xếp sử dụng và các chức năng bạn định sử dụng và sau đó sử dụng cprofile hoặc timeit để so sánh tốc độ hoạt động, tùy thuộc vào cách bạn cấu trúc dữ liệu của mình.

2
In [38]: data = numpy.random.rand(10000,10000) 

In [39]: %timeit data.sum(axis=0) 
10 loops, best of 3: 86.1 ms per loop 

In [40]: %timeit data.sum(axis=1) 
10 loops, best of 3: 101 ms per loop 
Các vấn đề liên quan