freeCodeCamp/guide/arabic/software-engineering/tco-tail-call-optimization/index.md

4.0 KiB

title localeTitle
TCO Tail Call Optimization TCO Tail Call Optimization

تحسين مكالمات الذيل (TCO)

يعتبر تحسين استدعاء الذيل ( TCO ) حلاً لمشكلة التكدس في المكدس عند القيام بالتكرار.

المشكلة

يتم دفع كل مكالمة لوظيفة إلى رصة في ذاكرة الكمبيوتر. عند انتهاء الدالة ، يتم إفراغها من المكدس. في التكرار ، تستدعي الوظيفة نفسها بحيث تستمر في الإضافة إلى المكدس حتى تنتهي جميع تلك الوظائف. هناك ، بالطبع ، حد لهذا المكدس. عندما يكون هناك عدد كبير من الوظائف يسمى ، يتم إضافة الكثير من المكالمات إلى المكدس. عندما تكون المكدس ممتلئة ويتم استدعاء دالة ، يؤدي ذلك إلى تجاوز سعة مكدس الذاكرة المؤقتة نظرًا لأن المكدس ممتلئ بالفعل. لن تنتهي الدالة العودية وستؤدي إلى حدوث خطأ.

مثال

في ما يلي مثال على وظيفة مختبِس جافا سكريبت باستخدام التكرار بدون TCO:

` function fact(x) { if (x <= 1) { return 1; } else { return x * fact(x-1); } }

console.log(fact(10)); // 3628800 console.log(fact(10000)); // RangeError: Maximum call stack size exceeded `

لاحظ أن تشغيل fact مع وسيطة 10000 سيؤدي إلى تجاوز سعة مكدس .

استخدام TCO لحل المشكلة

لحل هذه المشكلة باستخدام "تحسين مكالمات الذيل" ، يجب أن تكون العبارة التي تستدعي فيها الوظيفة نفسها في موضع ذيل. موضع الذيل هو العبارة الأخيرة التي سيتم تنفيذها في وظيفة. لذلك ، يجب أن يكون استدعاء الدالة إلى نفسها آخر شيء يسمى قبل انتهاء الدالة.

في المثال السابق ، يتم تنفيذ عملية الضرب الأخيرة في عبارة return x * fact(x-1) ، لذلك لم تكن العملية النهائية للدالة. لذلك ، فهي ليست دعوة الذيل الأمثل. من أجل أن تكون مكالمة ذيل محسنة ، تحتاج إلى إجراء المكالمة نفسها العملية الأخيرة للوظيفة.

مثال

في ما يلي مثال على وظيفة مفاعل جافا سكريبت (ES5) باستخدام التكرار مع TCO.

` function fact(n) { return factTCO(n, 1); }

function factTCO(x, acc) { if (x <= 1) { return acc; } else { return factTCO(x-1, x*acc); } }

console.log(fact(10)); // 3628800 console.log(fact(10000)); // Infinity - Number too large, but unlike the unoptimized factorial, this does not result in stack overflow. `

لاحظ أن تشغيل fact على 10000 هذه المرة لن يؤدي إلى تجاوز سعة الرصة عند تشغيلها في مستعرض يدعم ES6 لأن الاستدعاء إلى factTCO هو آخر عملية للدالة.

لماذا هذا يعمل

عندما يلاحظ المحول البرمجي أو المفسر أن المكالمة الذاتية هي العملية الأخيرة للدالة ، فإنها تنبثق الوظيفة الحالية وتدفع المكالمة الذاتية إلى المكدس. بهذه الطريقة لا يتم تغيير حجم المكدس. لذلك ، لا تتكدس المكدس بسبب الدالة.

ملاحظات

معلومات اكثر: