Có bất kỳ sự tối ưu hóa cuộc gọi đuôi nào ngoài việc đệ quy đuôi không? Tôi đã cố gắng để tìm hoặc nghĩ về một trong đó không liên quan đến đệ quy, nhưng không thành công. Có thể không? Bất kỳ ví dụ nào?Tối ưu hóa cuộc gọi đuôi bên cạnh đệ quy đuôi?
Trả lời
int bar(int x);
int foo(int x) { return bar(x); }
foo
chỉ có thể nhảy đến bar
ai trả cho người gọi trực tiếp; không có đệ quy nào là cần thiết ở bất cứ đâu.
Nhưng không phải là nội tuyến đơn giản này? Không thực sự là "tối ưu hóa cuộc gọi đuôi" IMO ... – dtech
@ddriver: Tôi chỉ lấy ra định nghĩa của 'bar', chỉ để lại tuyên bố của nó. Bạn không thể inline 'bar' mà không có định nghĩa của nó, nhưng bạn có thể thực hiện tối ưu hóa cuộc gọi đuôi trên người gọi của nó. Thấy sự khác biệt? – Mehrdad
Đây thực sự là một nửa của một cặp đệ quy có khả năng đệ quy của các hàm ... –
Chắc chắn, "tối ưu hóa cuộc gọi đuôi" thực tế là thuật ngữ cho loại tối ưu hóa này ở dạng tổng quát nhất, đệ quy-bất khả tri. Tối ưu hóa này không thay thế đệ quy bằng một vòng lặp while
hoặc một thứ gì đó tương tự. Thay vào đó, các cuộc gọi đuôi được chuyển đổi sao cho khung ngăn xếp của người gọi được sử dụng lại. Mọi mã của biểu mẫu return f(...)
hoặc f(...); return
đều có thể sửa đổi được. Nó hoạt động cho bất kỳf
, ngay cả đối với hàm con trỏ/đóng/phương pháp ảo nơi trình biên dịch không thể biết được những gì đang được gọi. Do đó, nó cũng hoạt động tốt hơn với các trình biên dịch riêng biệt, các hàm bậc cao hơn, kết thúc trễ, v.v.
Nếu bạn xem mã đủ, có chức năng hoặc bắt buộc, bạn sẽ tìm thấy các cuộc gọi không theo sau. Một trường hợp phổ biến là khi người gọi đại biểu đến callee cho nhiệm vụ chính và chỉ thực hiện một số chuẩn bị bổ sung. Trong mã chức năng, bạn thường sẽ tìm thấy nhiều chức năng nhỏ chỉ thực hiện một điều và được thực hiện theo các chức năng nhỏ khác, vì vậy bạn sẽ có một vài lớp áp dụng một phép biến đổi đơn giản cho các đối số, sau đó thực hiện cuộc gọi đuôi đến lớp tiếp theo (với dữ liệu được chuyển đổi làm đối số). TCO tối ưu hóa bước thứ hai, nó (lý tưởng) làm cho các cuộc gọi giá rẻ như một đơn giản jump
và làm cho các mã mô-đun đẹp, mất ít không gian ngăn xếp hơn là một thực hiện nguyên khối hơn. Trong một thiết kế hướng đối tượng có thể bạn muốn soạn một đối tượng của các đối tượng khác và tiếp xúc với các phương pháp tiện lợi mà đại biểu:
SomeClass doSomething(Argument a) {
log.debug("Doing something");
return this.somethingDoer.doIt(a, this.someExtraData);
}
Một ví dụ khác đó là về mặt kỹ thuật đệ quy lẫn nhau, nhưng thường chỉ có rất ít kích hoạt của bất kỳ chức năng nhất định (với hàng chục hoặc hàng trăm hoạt động khác ở giữa), là các máy trạng thái được triển khai bằng cách có một chức năng cho mỗi tiểu bang và gọi nó là nhập trạng thái đó:
void stateA() {
// do actual work
// determine which transition applies
stateB();
}
void stateB() {
// do actual work
// determine which transition applies
state...();
}
// dozens, possibly hundreds of other states
- 1. Scala có hỗ trợ tối ưu đệ quy đuôi không?
- 2. 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?
- 3. MATLAB có thực hiện tối ưu hóa cuộc gọi đuôi không?
- 4. Có thể tối ưu hóa cuộc gọi đuôi và RAII cùng tồn tại?
- 5. Có bất kỳ đuôi đuôi động cơ Javascript nào được tối ưu hóa không?
- 6. đuôi đệ quy trong OCaml
- 7. Có thể constexpr chức năng đánh giá làm đuôi đệ quy tối ưu hóa
- 8. Tại sao mã này ngăn chặn gcc & llvm từ tối ưu hóa cuộc gọi đuôi?
- 9. khai thác ngắn mạch và đuôi đệ quy
- 10. Frege có thực hiện tối ưu hóa cuộc gọi đuôi không?
- 11. Có thể bắt buộc tối ưu hóa cuộc gọi đuôi trên GCC/Clang không?
- 12. Liệu array_walk_recursive có sử dụng tối ưu hóa cuộc gọi đuôi không?
- 13. Clojure - đuôi sàng đệ quy của Eratosthenes
- 14. 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?
- 15. Chức năng này có sử dụng đệ quy đuôi không?
- 16. java.lang.StackOverflowError trong clojure đuôi đệ quy
- 17. Loại bỏ đệ quy đuôi là gì?
- 18. Tại sao đuôi này không đệ quy?
- 19. 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?
- 20. Loại bỏ cuộc gọi đuôi ở Clojure?
- 21. 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ì?
- 22. Chú thích Scala để đảm bảo chức năng đệ quy đuôi được tối ưu hóa là gì?
- 23. Xóa bỏ đệ quy không theo đuôi có lập trình
- 24. GHC có thể kết nối cuộc gọi tối ưu hóa các hành động IO không?
- 25. cắt đuôi đuôi ilabel
- 26. Làm cách nào để tắt tối ưu hóa đuôi trong gcc
- 27. Tối ưu hóa CTE cho các truy vấn đệ quy
- 28. Tối ưu hóa danh sách đệ quy Haskell
- 29. Đệ quy đệ quy và đệ quy đệ quy trong Erlang
- 30. tối ưu hóa bởi trình biên dịch trong một chương trình đệ quy
[Continuations] (http://en.wikipedia.org/wiki/Continuation -passing_style "Bài viết trên Wikipedia về 'Kiểu chuyển tiếp liên tục'") có thể đủ điều kiện để tối ưu hóa cuộc gọi đuôi. – stakx