Vì JavaScript không có cuộc gọi đuôi thực sự (chưa) những gì bạn đang gặp phải không phải là suy giảm dựa trên giá trị của z nhưng sự chậm lại dựa trên tăng trưởng ngăn xếp và khả năng thu dọn rác (GC) để dọn dẹp chồng các phạm vi cần thiết để giữ lại chức năng này.
Về lý thuyết, bạn có thể thay đổi hành vi này bằng cách sử dụng setImmediate và mẫu gọi lại để giải quyết vấn đề này. Việc sử dụng setImmediate cho phép phạm vi của vòng lặp thực hiện hiện tại không được sử dụng và được thu thập trong chu kỳ GC tiếp theo.
Vì vậy, một cái gì đó như:
var x = function x(z){
console.log(z);
if (z > 0) {
setImmediate(function(){
x(z-1);
});
}
};
Nhưng điều này sẽ không làm việc vì z được truyền xuống phạm vi cho setImmediate và do đó phạm vi trước đây của x không thể GC'd đúng cách.
Thay vào đó bạn phải sử dụng IIFE (Ngay Được triệu gọi hàm Expression) để đạt được những gì bạn đang tìm kiếm, kết hợp với việc sử dụng setImmediate để cho phép các chu kỳ thực hiện để có thời gian để cho phép GC:
var x = function x(z){
console.log(z);
if (z > 0) {
setImmediate((function(newZ){
return function(){
x(newZ);
};
})(z-1));
}
};
Trừ bất kỳ lỗi chính tả Tôi nghĩ rằng tôi đã đúng ở trên. Tất nhiên nếu bạn sử dụng ES6 bạn có thể viết tắt này rất nhiều là tốt.
Mặt khác của phương trình này là hiệu ứng spooling của console.log và bộ đệm thay đổi kích cỡ của bạn sẽ phải thực hiện điều này trong trình duyệt. Trong một thiết bị đầu cuối hệ điều hành các chi phí này sẽ được giảm thiểu như cuộn backbuffer bị giới hạn và bộ đệm phía sau được phân bổ trước và tái sử dụng.
Mất nhiều thời gian hơn vì nó đăng nhập vào bảng điều khiển thường xuyên hơn? Thật khó để tưởng tượng những gì họ muốn nghe. Bạn có hỏi họ không? – Bergi
Không, tôi chưa thể hỏi họ nhưng tôi sẽ làm nếu có thể. – beni0888
Nếu chúng thực sự có nghĩa là chậm hơn theo cấp số nhân với số lượng lớn 'z' so với số nhỏ, lý do thực sự duy nhất cho rằng chức năng ở đầu ngăn xếp cuộc gọi lớn sẽ bằng cách nào đó thực thi nhiều hơn và chậm hơn; rằng ngăn xếp cuộc gọi bằng cách nào đó sẽ tích lũy chi phí. Điều này rõ ràng phụ thuộc rất nhiều vào việc triển khai Javascript. Bạn có chạy bất kỳ thử nghiệm nào để xác nhận rằng điều này trên thực tế có chậm lại không? – deceze