Tránh chi phí của một cuộc gọi chức năng chỉ là một nửa câu chuyện.
làm:
- sử dụng
inline
thay vì#define
- các hàm rất nhỏ là ứng cử viên tốt cho
inline
: mã nhanh hơn và các tệp thực thi nhỏ hơn (nhiều cơ hội hơn trong bộ đệm mã)
- chức năng này nhỏ và được gọi rất thường xuyên
không:
- các hàm lớn: dẫn đến các tệp thực thi lớn hơn, làm suy giảm đáng kể hiệu năng bất kể việc thực thi nhanh hơn có kết quả từ chi phí gọi
- các hàm nội tuyến bị ràng buộc I / O
- chức năng hiếm khi được sử dụng
- hàm tạo và hàm hủy: ngay cả khi trống, trình biên dịch tạo mã cho chúng
- phá vỡ tính tương thích nhị phân khi phát triển thư viện:
- nội tuyến một chức năng hiện có
- thay đổi một hàm nội tuyến hoặc làm cho một hàm nội tuyến không phải là nội tuyến: phiên bản trước của thư viện gọi việc thực hiện cũ
khi phát triển thư viện, để tạo một lớp mở rộng trong tương lai, bạn nên:
- thêm hàm hủy ảo không nội tuyến ngay cả khi phần thân trống
- làm cho tất cả các hàm tạo không nội tuyến
- viết các triển khai phi tuyến của hàm tạo sao chép và toán tử gán trừ khi lớp không thể được sao chép theo giá trị
Hãy nhớ rằng inline
từ khóa là một gợi ý cho trình biên dịch: trình biên dịch có thể quyết định không nội tuyến một chức năng và nó có thể quyết định các chức năng nội tuyến không được đánh dấu inline
ở vị trí đầu tiên. Tôi thường tránh đánh dấu chức năng inline
(có thể ngoài việc viết các hàm rất rất nhỏ).
Về hiệu năng, cách tiếp cận khôn ngoan là (như mọi khi) để lập hồ sơ cho ứng dụng, sau đó cuối cùng inline
là một tập hợp các hàm đại diện cho nút cổ chai.
Người giới thiệu:
EDIT: Bjarne Stroustrup, Ngôn ngữ lập trình C ++:
Một chức năng có thể được xác định là inline
. Ví dụ:
inline int fac(int n)
{
return (n < 2) ? 1 : n * fac(n-1);
}
Trình inline
xác định là một gợi ý cho trình biên dịch rằng nó nên cố gắng tạo mã cho một cuộc gọi fac()
nội tuyến thay vì đặt mã cho hàm một lần và sau đó gọi qua cơ chế gọi hàm thông thường. Một trình biên dịch thông minh có thể tạo ra hằng số 720
cho một cuộc gọi fac(6)
. Khả năng các hàm nội tuyến đệ quy lẫn nhau, các hàm nội tuyến có lặp lại hay không phụ thuộc vào đầu vào, v.v., khiến cho không thể đảm bảo rằng mọi cuộc gọi của một inline
hàm thực sự được nội tuyến. Mức độ thông minh của trình biên dịch không thể được quy định, do đó, một trình biên dịch có thể tạo ra 720
, một trình biên dịch khác 6 * fac(5)
và một cuộc gọi khác không được thực hiện fac(6)
.
Để làm cho nội tuyến có thể xảy ra trong trường hợp không có các phương tiện biên dịch và liên kết thông minh khác thường, định nghĩa và không chỉ là khai báo của một hàm nội tuyến phải nằm trong phạm vi (§9.2). Một inline
đặc vụ không ảnh hưởng đến ngữ nghĩa của hàm. Cụ thể, một hàm nội tuyến vẫn có một địa chỉ duy nhất và static
các biến (§7.1.2) của hàm nội tuyến cũng vậy.
EDIT2: ISO-IEC 14882-1998, 7.1.2 Bộ chỉ định chức năng
Một khai báo hàm (8.3.5, 9.3, 11.4) với một bộ inline
xác định khai báo một hàm nội tuyến. Trình xác định nội tuyến chỉ ra cho việc thực hiện rằng việc thay thế nội tuyến của thân hàm tại điểm gọi sẽ được ưu tiên hơn đối với cơ chế gọi hàm thông thường. Việc triển khai là không bắt buộc để thực hiện thay thế nội tuyến này tại điểm gọi; tuy nhiên, ngay cả khi thay thế nội tuyến này bị bỏ qua, các quy tắc khác cho các hàm nội tuyến được xác định bởi 7.1.2 vẫn sẽ được tuân thủ.
inline
dành cho người mới sử dụng C ++, người mớiCFLAGS
đến Gentoo: không, biên dịch với-O3 -funroll-loops -finline-functions
sẽ không làm cho Pentium cũ của bạn bay lên;)