مقدمة: لماذا توصيف كود Rust؟
\n\nتشتهر Rust بسرعتها وأمانها، ولكن حتى أسرع كود يمكن أن يعمل ببطء إذا كان يحتوي على نقاط اختناق. التوصيف هو عملية قياس أداء البرنامج: وقت التنفيذ، تحميل المعالج، الذاكرة، ومقاييس أخرى. بالنسبة لمطوري Rust المبتدئين، هذه مهارة لا غنى عنها تسمح بتحويل الكود "العامل فقط" إلى كود فعال وسريع.
\n\nتخيل أنك كتبت محللاً للسجلات أو لعبة بلغة Rust. كل شيء يتم تجميعه، لكن البرنامج يعمل لفترة أطول من المتوقع. بدلاً من التخمين حول أي جزء من الكود يسبب البطء، يمكنك استخدام أدوات التوصيف التي ستظهر "النقاط الساخنة" (hotspots) بدقة. في هذه المقالة، سنستعرض الأدوات الأساسية لتوصيف Rust للمبتدئين: cargo-flamegraph و perf والقياسات البسيطة باستخدام std::time::Instant.
1. الطريقة الأسهل: قياس الوقت باستخدام std::time::Instant
\n\nقبل الانتقال إلى الأدوات المعقدة، تعلم كيفية قياس وقت تنفيذ أجزاء معينة من الكود. هذه طريقة أساسية لكنها فعالة للمبتدئين.
\n\nمثال: قياس وقت تنفيذ دالة
\n\nuse std::time::Instant;\n\nfn slow_function() {\n let mut sum = 0u64;\n for i in 0..1_000_000 {\n sum += i;\n }\n println!("المجموع: {}", sum);\n}\n\nfn main() {\n let start = Instant::now();\n slow_function();\n let duration = start.elapsed();\n println!("وقت التنفيذ: {:?}", duration);\n}\n\n\nسيخرج هذا الكود الوقت الدقيق لتشغيل slow_function. ومع ذلك، هذا الأسلوب غير مناسب للمشاريع الكبيرة: ستحتاج إلى وضع القياسات يدويًا في كل مكان مشبوه.
متى يكون هذا مفيدًا؟
\n- \n
- تريد التحقق بسرعة من فرضية حول دالة بطيئة. \n
- لا توجد إمكانية لتثبيت أدوات إضافية. \n
- أنت تعمل مع كود أحادي الخيط بدون منطق معقد. \n
العيب: القياسات اليدوية لا تظهر مقدار الوقت المستغرق داخل الدوال المستدعاة (مثل تخصيص الذاكرة أو استدعاءات النظام). لهذا تحتاج إلى أدوات التوصيف.
\n\n2. التوصيف باستخدام perf (لينكس)
\n\nأداة perf هي أداة توصيف قوية لنظام لينكس تعمل على مستوى النواة. تقوم بجمع عينات (samples) من حيث يقضي البرنامج وقته. للبدء، تأكد من تثبيت perf:
sudo apt install linux-tools-common linux-tools-generic # Ubuntu/Debian\n\n\nالخطوة 1: التجميع مع معلومات التصحيح
\nلكي يتمكن perf من عرض أسماء الدوال وأسطر الكود، قم بتجميع المشروع في وضع debug (أو release مع أعلام debuginfo):
cargo build\n# أو\nRUSTFLAGS="-g" cargo build --release\n\n\nالخطوة 2: تشغيل التوصيف
\nperf record -g ./target/debug/برنامجك\nperf report\n\n\nالعلم -g يقوم بتشغيل تسجيل مكدس الاستدعاءات (call graph). بعد تنفيذ perf report، سترى قائمة تفاعلية من الدوال مرتبة حسب وقت التنفيذ.
مثال على التفسير
\nلنفترض أنك ترى أن 70% من الوقت تستغرقه الدالة Vec::push. قد يعني هذا أنك تقوم بإعادة تخصيص الذاكرة بشكل متكرر. الحل: تخصيص سعة المتجه مسبقًا باستخدام Vec::with_capacity.
نصيحة: بالنسبة للمبتدئين، قد يبدو perf معقدًا بسبب كثرة البيانات. ابدأ بـ perf top في الوقت الفعلي لرؤية أي الدوال "ساخنة" الآن.
3. التصور باستخدام cargo-flamegraph
\n\nإذا كنت بحاجة إلى صورة مرئية، استخدم cargo-flamegraph. هذه الأداة تنشئ مخططات اللهب (flamegraphs) - رسوم بيانية حيث يعرض عرض المستطيل وقت تنفيذ الدالة، والعمق يظهر ع