Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

الأداء في الحلقات مقابل المكررات (Performance in Loops vs. Iterators)

لتحديد ما إذا كان يجب استخدام حلقات (loops) أو مكررات (iterators)، عليك معرفة أي تنفيذ هو الأسرع: نسخة دالة search التي تستخدم حلقة for صريحة، أم النسخة التي تستخدم iterators.

لقد أجرينا اختبار أداء (benchmark) عن طريق تحميل المحتوى الكامل لرواية The Adventures of Sherlock Holmes للمؤلف Sir Arthur Conan Doyle في سلسلة نصية (String) والبحث عن كلمة the في المحتوى. إليك نتائج الـ benchmark لنسخة search التي تستخدم حلقة for والنسخة التي تستخدم iterators:

test bench_search_for  ... bench:  19,620,300 ns/iter (+/- 915,700)
test bench_search_iter ... bench:  19,234,900 ns/iter (+/- 657,200)

كلا التنفيذين لهما أداء متقارب! لن نشرح كود الـ benchmark هنا لأن الهدف ليس إثبات أن النسختين متكافئتان، بل الحصول على فكرة عامة عن كيفية مقارنة هذين التنفيذين من حيث الأداء.

للحصول على benchmark أكثر شمولاً، يجب عليك التحقق باستخدام نصوص متنوعة وبأحجام مختلفة كـ contents ، وكلمات مختلفة وبأطوال مختلفة كـ query ، وجميع أنواع الاختلافات الأخرى. النقطة المهمة هي: المكررات، على الرغم من كونها تجريد عالي المستوى (high-level abstraction)، يتم تجميعها (compiled) إلى نفس الكود تقريباً كما لو كنت قد كتبت الكود منخفض المستوى بنفسك. المكررات هي واحدة من التجريدات صفرية التكلفة (zero-cost abstractions) في Rust، ونعني بذلك أن استخدام التجريد لا يفرض أي عبء وقت تشغيل (runtime overhead) إضافي. هذا يشبه الطريقة التي يعرّف بها Bjarne Stroustrup، المصمم والمنفذ الأصلي للغة ++C، مفهوم “صفر عبء” (zero-overhead) في عرضه التقديمي ETAPS لعام 2012 بعنوان “أسس ++C”:

بشكل عام، تلتزم تنفيذا ++C بمبدأ صفر عبء: ما لا تستخدمه، لا تدفع ثمنه. وعلاوة على ذلك: ما تستخدمه، لا يمكنك كتابته يدوياً بشكل أفضل.

في كثير من الحالات، يتم تجميع كود Rust الذي يستخدم iterators إلى نفس لغة التجميع (assembly) التي قد تكتبها يدوياً. يتم تطبيق تحسينات (optimizations) مثل فك الحلقات (loop unrolling) وإلغاء فحص الحدود (bounds checking) عند الوصول إلى المصفوفات، مما يجعل الكود الناتج فعالاً للغاية. الآن بعد أن عرفت هذا، يمكنك استخدام iterators والإغلاقات (closures) دون خوف! فهي تجعل الكود يبدو وكأنه من مستوى أعلى ولكنها لا تفرض عقوبة على أداء وقت التشغيل للقيام بذلك.

ملخص (Summary)

الإغلاقات والمكررات هي ميزات في Rust مستوحاة من أفكار لغات البرمجة الوظيفية (functional programming). فهي تساهم في قدرة Rust على التعبير بوضوح عن الأفكار عالية المستوى بأداء منخفض المستوى. إن تنفيذ closures و iterators مصمم بحيث لا يتأثر أداء وقت التشغيل. هذا جزء من هدف Rust للسعي لتوفير zero-cost abstractions.

الآن بعد أن قمنا بتحسين القدرة التعبيرية لمشروع الإدخال والإخراج الخاص بنا، دعونا نلقي نظرة على بعض الميزات الإضافية لـ cargo التي ستساعدنا في مشاركة المشروع مع العالم.