Tôi đang cố gắng viết một chương trình theo phong cách chức năng với C càng nhiều càng tốt. Tôi biết trình biên dịch tốt như GCC/Clang làm tối ưu hóa cuộc gọi đuôi âm thầm, nhưng nó không được bảo đảm. Có tùy chọn nào để buộc tối ưu hóa cuộc gọi đuôi trên các trình biên dịch không? (Tất nhiên khi chỉ có nó được gọi là ở cuối của chính nó)Có thể bắt buộc tối ưu hóa cuộc gọi đuôi trên GCC/Clang không?
Trả lời
Clang không thực hiện bất kỳ sự tối ưu nào. Có một thẻ LLVM pass tailcallelim
có thể làm những gì bạn muốn (nhưng nó không được bảo đảm). Bạn có thể chạy riêng nó với opt
.
Lựa chọn là gì? Tôi có thể có bất kỳ liên kết cho nó? – Eonil
opt là một công cụ dòng lệnh vận chuyển với llvm, http://llvm.org/cmds/opt.html –
Hoặc bạn có thể tinh chỉnh trình điều khiển clang để đảm bảo rằng nó chạy vượt qua một cách rõ ràng. –
Trong thực tế rất nhiều trình biên dịch cho C đã xử lý này cho bạn. Như eq đã đề cập bạn cũng có thể cho phép trình biên dịch xử lý hầu hết những thứ này thay vì cố tạo các tối ưu hóa sẽ không hoạt động ở nơi khác. Thông thường, bạn sẽ tìm thấy ngay cả khi bạn đặt cờ tối ưu hóa mà thực sự không có sự khác biệt về hiệu suất.
Một câu trả lời meta:
Có một số bài học đó là hữu ích để tiếp nhận vào C từ các ngôn ngữ chức năng: sử dụng chức năng, chức năng sử dụng nhỏ mà không đột biến hoặc globals hoặc đối số đầu vào, đừng sợ con trỏ hàm. Nhưng có giới hạn đối với những gì bạn có thể làm ở đây một cách hợp lý và dựa vào việc loại bỏ cuộc gọi đuôi ('đuôi gọi tối ưu hóa' không thực sự là thuật ngữ đúng) có lẽ ngoài những gì hữu ích. Bạn không thể buộc trình biên dịch sử dụng chiến lược này, và thậm chí nếu bạn có thể, kết quả C sẽ cực kỳ không đơn điệu, và khó đọc cho người khác, bao gồm cả bản thân tương lai của bạn.
Sử dụng ngôn ngữ cho điểm mạnh của chúng. C là tốt cho một số thứ, vì vậy hãy sử dụng nó cho những thứ đó, theo kiểu C tốt. Nếu bạn muốn những điểm mạnh khác nhau, hoặc nếu bạn muốn sử dụng một phong cách chức năng (quyết định tuyệt vời!), Hãy sử dụng một ngôn ngữ chức năng.
Nếu nó thực sự là một cuộc gọi đuôi sau đó một vòng lặp while hoặc một goto wont nhìn mà nhiều khác nhau từ một cuộc gọi đệ quy. Chỉ cần cập nhật tất cả các biến thay vì chuyển chúng thành các tham số. AFAIK đây là cách đa nền tảng duy nhất trong C để kiểm soát việc sử dụng ngăn xếp ở tất cả các mức tối ưu hóa. Nó thực sự có thể dễ đọc hơn vì bạn có một hàm khởi tạo theo sau bởi vòng lặp, nó khá là thành ngữ. Phiên bản đệ quy đuôi yêu cầu hai hàm, một cho khởi tạo và một cho phần đệ quy.
- 1. Có thể tối ưu hóa cuộc gọi đuôi và RAII cùng tồn tại?
- 2. MATLAB có thực hiện tối ưu hóa cuộc gọi đuôi không?
- 3. Liệu array_walk_recursive có sử dụng tối ưu hóa cuộc gọi đuôi không?
- 4. Tối ưu hóa cuộc gọi đuôi bên cạnh đệ quy đuôi?
- 5. Frege có thực hiện tối ưu hóa cuộc gọi đuôi không?
- 6. GHC có thể kết nối cuộc gọi tối ưu hóa các hành động IO không?
- 7. Tại sao mã này ngăn chặn gcc & llvm từ tối ưu hóa cuộc gọi đuôi?
- 8. Tôi có thể xây dựng một cuộc gọi đuôi được gọi là biểu thức tối ưu đệ quy không?
- 9. Trạng thái hiện tại của tối ưu hóa cuộc gọi đuôi cho F # trên Mono (2.11) là gì?
- 10. Có bất kỳ đuôi đuôi động cơ Javascript nào được tối ưu hóa không?
- 11. Tại sao tối ưu hóa cuộc gọi đuôi không được sử dụng trong chương trình Haskell này?
- 12. Có thể constexpr chức năng đánh giá làm đuôi đệ quy tối ưu hóa
- 13. Có thể tối ưu hóa chức năng này không?
- 14. tối ưu hóa ràng buộc trong R
- 15. Scala có hỗ trợ tối ưu đệ quy đuôi không?
- 16. Không thể tối ưu hóa bảng innoDB
- 17. Mã này có thể được tối ưu hóa không?
- 18. Tôi có thể tối ưu hóa bản sao Mercurial không?
- 19. Chức năng foldl được viết lại của tôi có được tối ưu hóa không?
- 20. Điều gì có thể làm cho mã F # không được tối ưu hóa nhanh hơn mã được tối ưu hóa?
- 21. tối ưu hóa quadprog
- 22. Tối ưu hóa được quản lý cho các cuộc gọi gốc
- 23. Tối ưu hóa CVPixelBufferRef
- 24. Tôi có hiểu chính xác tối ưu hóa sớm không?
- 25. Tối ưu hóa CALayer?
- 26. Tối ưu hóa các cuộc gọi tiếp theo đến số nguyên và modulo (phần còn lại)
- 27. Tối ưu hóa Java: biến cục bộ hoặc gọi hàm
- 28. Trong .NET, các cuộc gọi phương thức trống sẽ được tối ưu hóa?
- 29. Loại bỏ cuộc gọi đuôi ở Clojure?
- 30. Tại sao scalac không thể tối ưu hóa đệ quy đuôi trong các tình huống nhất định?
Trình biên dịch có lẽ khá thông minh về vấn đề này, chỉ cần tin tưởng nó. Không cần hack * không di động *. –
Bạn muốn điều gì xảy ra trong trường hợp bạn cho rằng tối ưu hóa đuôi nên xảy ra nhưng trình biên dịch không có khả năng thực hiện nó (vì bất kỳ lý do gì)? –
@Michael Tôi mong đợi một lỗi thời gian biên dịch nếu tối ưu hóa cuộc gọi đuôi buộc là không thể được thực hiện. – Eonil