Có lý do hiệu suất nào để khai báo các tham số phương thức cuối cùng trong Java không?


117

Có lý do hiệu suất nào để khai báo các tham số phương thức cuối cùng trong Java không?

Như trong:

public void foo(int bar) { ... }

Đấu với:

public void foo(final int bar) { ... }

Giả sử rằng barnó chỉ được đọc và không bao giờ được sửa đổi trong foo().


Tôi không thể nghĩ ra lý do tại sao trình biên dịch sẽ quan tâm nếu bạn đã khai báo một tham số phương thức cuối cùng hay không. Nhưng câu trả lời thực sự cho câu hỏi này là - viết hai hàm, một với các tham số cuối cùng và một với các tham số thông thường. Chạy chúng hàng triệu lần mỗi lần và xem liệu có bất kỳ sự khác biệt đáng chú ý nào về thời gian chạy hay không. Nếu bạn lo lắng về hiệu suất, điều rất quan trọng là phải thực hiện một số công việc lập hồ sơ trên mã của bạn và tìm ra chính xác điều gì đang làm bạn chậm lại. Nó gần như chắc chắn không phải là những gì bạn mong đợi :)
Mike Blandford

1
Tôi đề nghị bạn không bao giờ viết điểm chuẩn vi mô. Bạn không biết được tối ưu hóa các JIT có thể làm và khi nào, và bạn có thể sẽ nhận được một ý tưởng sai lầm về cách hành xử chỉ làm một "trường hợp thử nghiệm đơn giản"
Edmondo1984

cũng có thể được, nhưng không có ai ở đây đã viết hoặc đề nghị một microbenchmark ...
Kip

1
Câu trả lời của @Mike Blandford đề xuất sử dụng điểm chuẩn vi mô phải không?
Ben Page

Viết các tiêu chuẩn vi trong Java là một cái gì đó rất rất khó khăn
Edmondo1984

Câu trả lời:


97

Từ khóa cuối cùng không xuất hiện trong tệp lớp cho các biến và tham số cục bộ, do đó nó không thể tác động đến hiệu suất thời gian chạy. Nó chỉ có công dụng là làm rõ ý định của người viết mã rằng biến không được thay đổi (mà nhiều người cho là lý do đáng ngờ cho việc sử dụng nó) và xử lý các lớp ẩn danh bên trong.

Có rất nhiều tranh cãi về việc liệu công cụ sửa đổi cuối cùng trên chính phương thức có tăng hiệu suất hay không vì dù sao thì các phương thức sẽ được trình biên dịch tối ưu hóa trong thời gian chạy, bất kể công cụ sửa đổi là gì. Trong trường hợp này, nó cũng chỉ nên được sử dụng để hạn chế việc ghi đè phương thức.


5
bạn sẽ nghĩ rằng các biến thức / params có thể được tối ưu hóa cho các biến lặp mặc dù ... nhưng một trình biên dịch tốt / runtime nên có thể con số này ra mà không nào cuối cùng ...
John Gardner

9
Tôi đã thấy trình biên dịch của Sun phát ra mã bytecode ngắn hơn một chút khi sự khác biệt duy nhất giữa hai phương pháp là "tính cuối cùng" của các biến cục bộ. Các tối ưu hóa vi mô là một điều thực tế và các trình biên dịch thực sự tạo ra chúng. Tất nhiên, điều thực sự quan trọng là JIT làm gì với bytecode và các tham chiếu cục bộ sẽ mất "tính cuối cùng" của chúng khi được biên dịch sang bytecode. Tôi nghĩ đây là lý do tại sao có quá nhiều suy đoán về các biến cục bộ cuối cùng: nó khá không xác định được kết quả là gì. Tuy nhiên, việc sử dụng các địa phương cuối cùng có thể ảnh hưởng đến mã bytecode - đối với giá trị của nó.
Christopher Schultz

Vì nó không mang tính xác định, thực sự không có bất kỳ cách nào để phụ thuộc vào việc tối ưu hóa. Tất nhiên, nhiều thứ có thể đã thay đổi trong việc triển khai VM kể từ câu trả lời ban đầu vào năm 2008 ;-)
Robin

15

Lợi ích duy nhất của tham số cuối cùng là nó có thể được sử dụng trong các lớp lồng nhau ẩn danh. Nếu một tham số không bao giờ được thay đổi, trình biên dịch sẽ phát hiện ra điều đó như một phần của hoạt động bình thường ngay cả khi không có công cụ sửa đổi cuối cùng. Khá hiếm khi xảy ra lỗi do một tham số được gán bất ngờ - nếu các phương thức của bạn đủ lớn để cần mức độ kỹ thuật này, hãy làm cho chúng nhỏ hơn - các phương thức bạn gọi không thể thay đổi các tham số của bạn.


8
"Khá hiếm khi xảy ra lỗi do một tham số được gán bất ngờ". Nó phổ biến hơn bạn nghĩ ...
RAY

2
@RAY bạn có thể đúng, thực ra tôi không có bất kỳ dữ liệu nào (ngoài kinh nghiệm của riêng tôi) để sao lưu xác nhận quyền sở hữu đó.
Dobes Vandermeer 23/02/12

Nói chính xác hơn là @DobesVandermeer, đó không thực sự là "lợi ích đối với thông số cuối cùng ". Những gì bạn đang mô tả chỉ là cú pháp bắt buộc đơn giản để bất kỳ biến cục bộ nào (mà tôi đang bao gồm các tham số là) được hiển thị cho phạm vi cục bộ của lớp lồng nhau ẩn danh.
swooby

0

Các trình biên dịch hoạt động sau khi tải lớp, chẳng hạn như trình biên dịch JIT, có thể tận dụng các phương thức cuối cùng. Do đó, các phương thức được khai báo cuối cùng có thể có một số lợi ích về hiệu suất.

http://www.javaperformancetuning.com/tips/final.shtml

Ồ và một nguồn tốt khác

http://mindprod.com/jgloss/final.html


10
Câu hỏi là về các tham số được khai báo cuối cùng, không có tác động đến hiệu suất.
Robin

Trên JIT'S (Điểm phát sóng) hiện đại, cuối cùng không có bất kỳ ảnh hưởng hiệu suất (có thể đo lường) nào, cho dù được áp dụng cho các tham số hay lớp
kohlerm

2
Hai bài báo bạn liên kết đều gợi ý rằng cuối cùng là một dấu hiệu ngữ nghĩa cho các nhà phát triển và rằng các trình biên dịch JIT có thể sử dụng cuối cùng (nhưng như những người khác đã chỉ ra, họ không thực sự cần thông tin đó). Vì vậy, cuối cùng là khá về ngữ nghĩa, song song với các trình biên dịch C / ++ hiện đại, khả năng suy ra hằng số của các biến và phương thức ngay cả khi chúng không được đánh dấu const rõ ràng.
ron

0

Chỉ một điểm nữa ở trên đó là sử dụng các biến cục bộ không cuối cùng được khai báo trong phương thức — thể hiện lớp bên trong có thể tồn tại lâu hơn khung ngăn xếp, vì vậy biến cục bộ có thể biến mất trong khi đối tượng bên trong vẫn còn sống


-2

Tôi giả sử rằng trình biên dịch có thể loại bỏ tất cả các biến cuối cùng tĩnh riêng tư có kiểu nguyên thủy, chẳng hạn như int và nội tuyến chúng trực tiếp trong mã giống như với macro C ++.

Tuy nhiên, tôi không có manh mối nếu điều này được thực hiện trong thực tế, nhưng nó có thể được thực hiện để tiết kiệm một số bộ nhớ.


Câu hỏi không phải về các biến cuối cùng của private statc.
Marquis of Lorne,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.