2014-11-06 14 views
7

Tôi đã chọn những con số này một cách ngẫu nhiên, nhưng những kết quả này có vẻ phù hợp --- một số mũ nổi nhanh hơn 25% -50% so với số nguyên. Các cách xử lý này khác nhau như thế nào?Tại sao chậm hơn numpy.power cho số nguyên?

In [209]: %timeit -n 100000 -r 100 np.power(3.71242, 7) 
100000 loops, best of 100: 3.45 µs per loop 

In [210]: %timeit -n 100000 -r 100 np.power(3.71242, 7.0) 
100000 loops, best of 100: 1.98 µs per loop 
+0

Nếu tôi đã phải mạo hiểm một dự đoán, numpy hy vọng một phao nhưng nhận được một int và cần thiết để chuyển đổi. –

+0

@JeffMercado ý tưởng thú vị --- nhưng nó dường như không thêm lên: "% timeit -n 100000 -r 10 if (type (2) == int): float (2)" ==> "100000 vòng lặp, tốt nhất là 10: 571 ns trên mỗi vòng lặp " – DilithiumMatrix

+0

Tôi nghi ngờ rằng một số mũ int gây ra phép nhân thực tế trong khi một số mũ nổi gây ra việc sử dụng các bản ghi. –

Trả lời

13

np.poweruniversal function (ufunc). Các hàm này có thể được sử dụng trên các scalars và mảng có nhiều kiểu dữ liệu khác nhau, nhưng trước tiên phải kiểm tra kiểu giá trị đầu vào để chúng có thể xác định vòng lặp nội bộ để sử dụng để tạo ra các giá trị đầu ra phù hợp.

Nếu loại đầu vào không ánh xạ tới bất kỳ vòng lặp được xác định trước của ufunc, thì ufunc sẽ cố gắng cast the input values to suitable types (trừ khi được thông báo khác). Việc kiểm tra và chuyển đổi các giá trị đầu vào này có chi phí hiệu năng được liên kết với nó, giải thích thời gian được quan sát trong câu hỏi.

Thuộc tính types của ufunc cho biết cách các kiểu dữ liệu đầu vào sẽ ánh xạ tới kiểu dữ liệu đầu ra. Dưới đây là danh sách các ánh xạ cho np.power:

>>> np.power.types # 'input input -> output' 
['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 
'QQ->Q', 'ee->e', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G', 'OO->O'] 

số Floating-point thuộc về mã ký tự 'g', Python số nguyên thuộc về 'l'. Danh sách đầy đủ các mã ký tự này có thể được tìm thấy here.

Lưu ý rằng đối với ufunc này, các kiểu dữ liệu của hai giá trị đầu vào phải giống nhau. Ví dụ: không có ánh xạ cho kết hợp các kiểu dữ liệu đầu vào là floatint.

Nhưng chúng tôi vẫn có thể cung cấp cho np.power các kiểu dữ liệu khác nhau và để cho nó truyền các giá trị cho các kiểu dữ liệu thích hợp. Đối với một float và một int, một số float64 được trả về:

>>> np.power(3.71242, 7).dtype 
dtype('float64') 

Ở trên bạn có thể thấy rằng các đầu vào chỉ mà bản đồ để mã float64 nhân vật g là hai g giá trị khác: 'gg->g'.

Vì vậy, đằng sau hậu trường, np.power(3.71242, 7) đã lấy một mã số float và Python int và phải quyết định xem nó có thể khôi phục lại an toàn và loại nào. Giá trị int được quảng cáo an toàn cho loại phao g. Sau đó, ufunc biết vòng lặp nào để chạy và trả lại giá trị g khác.

Vì lý do này, không trộn các kiểu dữ liệu đầu vào dẫn đến hiệu suất tốt hơn cho np.power.

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