Khi nào nên sử dụng nội tuyến trong Rust?


85

Rust có một thuộc tính "nội tuyến" có thể được sử dụng ở một trong ba hương vị đó:

#[inline]

#[inline(always)]

#[inline(never)]

Khi nào chúng nên được sử dụng?

Trong tham chiếu Rust, chúng ta thấy một phần thuộc tính nội tuyến cho biết

Trình biên dịch tự động nội dòng các chức năng dựa trên cơ sở dữ liệu nội bộ. Các hàm nội tuyến không chính xác thực sự có thể làm cho chương trình chậm hơn, vì vậy nó nên được sử dụng cẩn thận.

Trong diễn đàn Rust Internals, huon cũng bảo thủ về việc chỉ định nội tuyến .

Nhưng chúng tôi thấy việc sử dụng đáng kể trong nguồn Rust, bao gồm cả thư viện chuẩn. Rất nhiều thuộc tính nội tuyến được thêm vào các hàm một dòng, điều này sẽ giúp trình biên dịch dễ dàng phát hiện và tối ưu hóa thông qua phương pháp phỏng đoán theo tham chiếu. Những điều đó trong thực tế không cần thiết?

Câu trả lời:


69

Một hạn chế của trình biên dịch Rust hiện tại là nếu bạn không sử dụng LTO (Tối ưu hóa thời gian liên kết), nó sẽ không bao giờ nội dòng một chức năng không được đánh dấu #[inline]trên các thùng. Rust sử dụng một mô hình biên dịch riêng biệt tương tự như C ++ vì việc triển khai LTO của LLVM không mở rộng quy mô tốt cho các dự án lớn. Do đó, các chức năng nhỏ tiếp xúc với các thùng khác cần được đánh dấu bằng tay. Đây không phải là một tình huống tuyệt vời và nó có khả năng sẽ được khắc phục trong tương lai bằng sự kết hợp của một số cải tiến đối với nội tuyến LTO và MIR.

#[inline(never)]đôi khi hữu ích để gỡ lỗi (tách một đoạn mã không hoạt động như mong đợi). Về lý thuyết, nó có thể được sử dụng để đo điểm chuẩn, nhưng đó thường là một ý tưởng tồi: tắt nội tuyến không ngăn cản các tối ưu hóa liên thủ tục khác như truyền liên tục. Về mặt mã thông thường, nó có thể giảm kích thước mã nếu bạn có một chức năng trợ giúp được sử dụng thường xuyên chỉ được sử dụng để xử lý lỗi.

#[inline(always)]nói chung là ý kiến ​​tồi; nếu một hàm đủ lớn để trình biên dịch không nội tuyến nó theo mặc định, nó đủ lớn để chi phí của cuộc gọi không thành vấn đề (và nội dòng quá mức sẽ làm tăng áp lực bộ nhớ đệm lệnh). Có những trường hợp ngoại lệ, nhưng bạn cần các phép đo hiệu suất để chứng minh điều đó. Ví dụ này là loại tình huống đáng xem xét. #[inline(always)]cũng có thể được sử dụng để cải thiện -O0chất lượng mã, nhưng điều đó thường không đáng lo ngại.


19
lưu ý rằng nó inline(never)được sử dụng trên bản chất hoảng loạn để đảm bảo rằng trình tối ưu hóa không nội tuyến các hàm chỉ được gọi trong trường hợp hoảng loạn.
oli_obk

4
-1 bởi vì có điều gì đó thiếu sót đến điểm đầu tiên. Các mục chung có thể được nội tuyến trên các thùng, vì chúng được biên dịch hiệu quả khi được khởi tạo, do đó, mã cần thiết cho nội tuyến luôn có sẵn. Và điều này có nghĩa là một số lượng lớn các mặt hàng không được đánh dấu vẫn có thể được đặt trong thùng chéo. Trong một số loại thùng thư viện cơ bản, mọi mục đều chung chung!
bluss
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.