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

68 lines
4.0 KiB
Markdown
Raw Normal View History

---
title: TCO Tail Call Optimization
localeTitle: 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` هو آخر عملية للدالة.
### لماذا هذا يعمل
عندما يلاحظ المحول البرمجي أو المفسر أن المكالمة الذاتية هي العملية الأخيرة للدالة ، فإنها تنبثق الوظيفة الحالية وتدفع المكالمة الذاتية إلى المكدس. بهذه الطريقة لا يتم تغيير حجم المكدس. لذلك ، لا تتكدس المكدس بسبب الدالة.
### ملاحظات
#### معلومات اكثر:
* [ما هو optmization دعوة الذيل؟](https://stackoverflow.com/questions/310974/what-is-tail-call-optimization) (ستاكوفيرفلوو)
* [تحسين استدعاء الذيل في ECMAScript 6](http://2ality.com/2015/06/tail-call-optimization.html) (2ality - مدونة Dr. Axel Rauschmayer)