Bất chấp những sự giảm giá không công bằng, câu hỏi có ý nghĩa nhiều vì nó cho thấy lỗi JVM thực sự.
Khi bạn chạy Oracle JDK hiệu suất của Math.pow(x, 2.0)
rất khác nhau giữa các phiên bản JVM.
- Trước JDK 7u40
Math.pow
sử dụng thực hiện các phần mềm, tức là nó chỉ đơn giản là gọi __ieee754_pow chức năng mô phỏng các hoạt động trong phần mềm. Đó là khá chậm, nhưng nó đã có một trường hợp đặc biệt cho y == 2.
- Kể từ khi JDK 7u40
Math.pow
trở thành một JVM nội tại đã được dịch sang hướng dẫn FPU bởi JIT. Tuy nhiên, với tối ưu hóa này trường hợp đặc biệt đã bị mất, dẫn đến hồi quy hiệu suất cho y == 2, xem bug JDK-8029302.
- Hồi quy hiệu suất này đã được sửa trong JDK 8u25 và 7u80 sắp tới. Vì JDK 8u25
Math.pow
hoạt động đủ nhanh cho tất cả các giá trị, nhưng cực kỳ nhanh đối với y == 2. Xem related question.
P.S. Thời gian xấp xỉ tính bằng giây đối với các yêu cầu 100M Math.pow
trên máy của tôi với các phiên bản JDK khác nhau.
Math.pow(x, 2.0) Math.pow(x, 2.0000001)
JDK 7u25 3.0 30.4
JDK 7u40 11.1 11.1
JDK 8u40 0.1 11.1
Việc triển khai miễn phí để chi tiêu chi nhánh có điều kiện để kiểm tra trường hợp đặc biệt hoặc thực hiện tất cả các trường hợp có cùng mã. Tất cả những gì quan trọng là kết quả. Không có đảm bảo về thời gian thực hiện. (Không phải vậy, nếu bạn không cẩn thận, bạn sẽ thấy chúng ngay cả khi chúng ở đó). –
Tại sao bạn mong đợi tăng hiệu suất? Kiểu của cả hai tham số là 'double'. –
Bởi vì nó chỉ sử dụng một thực hiện phép thuật đó là chuyên ngành cho tất cả các đôi; nó không sử dụng bất kỳ phép thuật đặc biệt nào cho sức mạnh số nguyên. Nếu bạn chỉ sử dụng phép nhân trực tiếp ('x * x') bạn sẽ nhận được kết quả tốt hơn. –