2012-03-14 31 views
43

Các documentation trạng thái:Có lý do nào để không sử dụng pragma INLINABLE cho một chức năng không?

Một {- # INLINABLE f # -} pragma trên một hàm f có các hành vi sau đây:

  • Trong khi INLINE nói "xin vui lòng inline tôi", các INLINABLE nói "cảm thấy tự do để inline tôi, sử dụng theo ý của bạn". Nói cách khác, lựa chọn được để lại cho GHC, sử dụng các quy tắc tương tự như đối với các chức năng không có pragma. Không giống như INLINE, quyết định đó được thực hiện tại trang web cuộc gọi và do đó sẽ bị ảnh hưởng bởi ngưỡng nội tuyến, mức tối ưu hóa, v.v.

  • Giống như INLINE, pragma INLINABLE giữ bản sao RHS gốc cho mục đích nội tuyến và vẫn tồn tại nó trong tệp giao diện, bất kể kích thước của RHS.

  • Một cách để sử dụng INLINABLE kết hợp với nội tuyến chức năng đặc biệt (Mục 7.18, “Các chức năng tích hợp đặc biệt”). Các cuộc gọi inline f cố gắng rất khó để inline f. Để đảm bảo rằng f có thể được gạch chân, bạn nên đánh dấu định nghĩa của f là INLINABLE, để GHC đảm bảo phơi bày một sự mở ra bất kể nó lớn như thế nào. Hơn nữa, bằng cách chú thích f là INLINABLE, bạn đảm bảo rằng RHS gốc của f được gạch chân, thay vì bất kỳ phiên bản tối ưu hóa ngẫu nhiên nào của trình tối ưu hóa f GHC đã tạo ra.

  • Pragma INLINABLE cũng hoạt động với SPECIALIZE: nếu bạn đánh dấu hàm f là INLINABLE, sau đó bạn có thể SPECIALIZE trong một mô-đun khác (xem Phần 7.16.8, “SPECIALIZE pragma”).

  • Không giống như INLINE, bạn có thể sử dụng một pragma INLINABLE trên một hàm đệ quy. Lý do chủ yếu làm để như vậy để cho phép sử dụng sau này của chuyên

nhược điểm của nó là gì?

Ứng dụng có tạo tệp giao diện nhiều, lớn hơn nhiều không? Liệu nó có biên dịch chậm hơn nhiều không?

Có lý do nào tôi không nên đặt một pragma INLINABLE vào mọi chức năng được xuất mà tôi viết không? Có lý do nào GHC không đặt một pragma INLINABLE vào mọi chức năng xuất khẩu mà tôi viết không?

Trả lời

49

Có ba sự khác biệt giữa việc sử dụng INLINABLE và không sử dụng một pragma tại tất cả:

  • Without INLINABLE, định nghĩa mà đi trong file giao diện là mã sau tối ưu hóa, trong khi với INLINABLE, nó là mã bạn viết (nhiều hay ít). Đặc biệt, không có INLINABLE, GHC có thể nội tuyến các hàm khác vào định nghĩa của hàm.

  • Không có INLINABLE, GHC sẽ bỏ qua định nghĩa từ tệp giao diện nếu tệp quá lớn. Nếu một số chức năng khác được đưa vào bên phải, điều này có thể dễ dàng đẩy nó vượt quá giới hạn.

  • INLINABLE cũng bật một số máy móc thông minh tự động chuyên chức năng quá tải nơi chúng được sử dụng và chia sẻ các phiên bản chuyên biệt với các mô-đun khác chuyển nhập quá mức mô-đun trong đó phiên bản chuyên biệt đã được tạo.

+9

Tôi đang cố gắng hiểu các phân nhánh thực tế. Điểm đầu tiên có nghĩa là khi hàm không được gạch chân, nó sẽ sử dụng mã chưa được tối ưu hóa và chậm hơn không? Hoặc nó sẽ chậm hơn nếu nó có được inlined nhưng RULES không cháy? Hay đôi khi nó sẽ nhanh hơn, đôi khi chậm hơn trên cơ sở từng trường hợp? Về điểm thứ hai, có bất kỳ hạn chế nào để đưa nó vào tệp giao diện ngoài không gian đĩa không? Họ có thể nhận được quá lớn mà nó là một vấn đề (đĩa lớn)? Và lại: điểm thứ ba, liệu có lý do nào đó không phải là một điều tốt đẹp không? Nó có thể gây ra một số vấn đề mã bloat? – glaebhoerl

+4

Tôi cố ý tránh nói về các nhánh thực tế, vì phần lớn tôi không chắc chắn :-) Tôi đã thuyết phục Simon PJ thêm INLINABLE vì tôi muốn một biến thể của INLINE không gây ra quá nhiều mã, bằng cách sử dụng GHC phỏng đoán khá tinh vi về thời điểm nội tuyến. Để trả lời câu hỏi đầu tiên của bạn: không, cũng sẽ có một phiên bản được tối ưu hóa của hàm được biên dịch thành mô-đun ban đầu (như với INLINE), và điều này sẽ được sử dụng cho các cuộc gọi không được gạch chân. Bao gồm rất nhiều định nghĩa chức năng trong giao diện có thể làm chậm mọi thứ. –

+0

Hmm, được rồi. Sẽ rất hay khi có một số hướng dẫn về thời điểm sử dụng và khi không sử dụng, nhưng tôi đoán tôi sẽ phải thử nghiệm. :) – glaebhoerl

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