Việc đệ quy có thể thất bại nhanh hơn vì chức năng đệ quy vô hạn sẽ thổi ra ngăn xếp tạo ra ngoại lệ mà chương trình có thể phục hồi, trong khi một giải pháp lặp lại sẽ chạy cho đến khi bị dừng bởi tác nhân bên ngoài.
Đối với mã sẽ tạo ra kết quả đầu ra hợp lệ cho thời gian, chi phí chính của đệ quy là phí gọi hàm. Các giải pháp lặp đi lặp lại đơn giản là không có điều này, do đó, có xu hướng giành chiến thắng trong mã hiệu suất quan trọng bằng các ngôn ngữ không tối ưu hóa rõ ràng cho đệ quy.
Nó chắc chắn đáng chú ý trong điểm chuẩn, nhưng trừ khi bạn đang viết mã quan trọng hiệu suất, người dùng của bạn có thể sẽ không nhận thấy.
Điểm chuẩn tại http://jsperf.com/function-call-overhead-test cố gắng định lượng chi phí cuộc gọi chức năng trong các phiên dịch JS khác nhau. Tôi sẽ đặt cùng một điểm chuẩn tương tự như kiểm tra một cách rõ ràng đệ quy nếu bạn lo lắng.
Lưu ý rằng đuôi gọi đệ quy tối ưu hóa là khó khăn để làm một cách chính xác trong ECMAScript 3.
Ví dụ, một thực hiện đơn giản của mảng gấp trong JavaScript:
function fold(f, x, i, arr) {
if (i === arr.length) { return x; }
var nextX = f(x, arr[i]);
return fold(f, nextX, i+1, arr);
}
không thể mòn đuôi được tối ưu hóa vì cuộc gọi
fold(eval, 'var fold=alert', 0, [0])
sẽ eval('var fold=alert')
bên trong cơ thể của fold
, gây ra các cuộc gọi dường như đệ quy đuôi để fold
để không thực sự đệ quy.
ECMAScript 5 thay đổi eval
để không callable trừ thông qua tên eval
, và chế độ nghiêm ngặt ngăn eval
từ giới thiệu các biến địa phương, nhưng tối ưu hóa đuôi gọi phụ thuộc vào khả năng để xác định tĩnh nơi một cái đuôi gọi đi mà không phải lúc nào có thể bằng các ngôn ngữ động như JavaScript.
Bạn có thể thử điểm chuẩn nó. Nếu nó là một mảng nhỏ, tôi sẽ đi với giải pháp dễ đọc nhất. –