تحليل أداء كود Rust: إيجاد نقاط الاختناق عمليًا

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

تحليل أداء كود Rust: إيجاد نقاط الاختناق عمليًا

\n\n

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

\n\n

لماذا يعتبر تحليل الأداء مهمًا لـ Rust؟

\n\n

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

\n\n
    \n
  • ما هي الدوال التي تستهلك معظم وقت المعالج (CPU)؟
  • \n
  • أين تحدث تخصيصات الذاكرة المتكررة؟
  • \n
  • ما هي أجزاء الكود التي تمنع التنفيذ (مثلًا بسبب الميوتكسات)؟
  • \n
  • ما مدى كفاءة استخدام ذاكرة التخزين المؤقت للمعالج؟
  • \n
\n\n

أدوات تحليل أداء Rust

\n\n

دعنا نستعرض ثلاثة أساليب رئيسية تغطي 90% من مهام تحليل الأداء.

\n\n

1. قياس الأداء المدمج باستخدام cargo bench

\n\n

أبسط طريقة هي استخدام cargo bench من نظام Rust البيئي. يسمح لك بقياس وقت تنفيذ دوال معينة.

\n\n

مثال لقياس أداء دالة تقوم بفرز مصفوفة:

\n\n
// benches/my_bench.rs\nuse criterion::{black_box, criterion_group, criterion_main, Criterion};\n\nfn sort_benchmark(c: &mut Criterion) {\n    let mut data: Vec<i32> = (0..10000).rev().collect();\n\n    c.bench_function("sort 10k", |b| {\n        b.iter(|| {\n            // black_box يمنع تحسينات المترجم\n            let mut clone = black_box(data.clone());\n            clone.sort();\n            black_box(clone)\n        })\n    });\n}\n\ncriterion_group!(benches, sort_benchmark);\ncriterion_main!(benches);
\n\n

التشغيل: cargo bench

\n\n

ستحصل على تقرير بالوقت والانحراف المعياري والمقارنة مع عمليات التشغيل السابقة. هذا مثالي لاختبار الانحدار في الأداء.

\n\n

2. محلل الأداء النظامي perf (لينكس)

\n\n

perf هي أداة قوية من نواة لينكس. تجمع عينات من عدادات الأداء (دورات المعالج، أخطاء الذاكرة المؤقتة، التعليمات) دون تعديل الكود.

\n\n

الاستخدام الأساسي:

\n\n
# جمع البيانات\nperf record -F 99 --call-graph dwarf ./my_rust_program\n\n# عرض التقرير\nperf report --stdio\n\n# إنشاء flamegraph\nperf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg
\n\n

العلامة -F 99 تحدد تردد أخذ العينات 99 هرتز (عادةً ما يكون كافيًا). --call-graph dwarf يتضمن تسجيل مكدس الاستدعاءات. الناتج هو flamegraph تفاعلي (SVG)، حيث المحور X يمثل الوقت، والمحور Y يمثل مكدس الاستدعاءات. عرض المستطيل يوضح مقدار الوقت الذي استغرقته الدالة.

\n\n

3. أداة flamegraph لـ Rust

\n\n

توجد أداة متخصصة cargo-flamegraph تبسط إنشاء flamegraph لمشاريع Rust:

\n\n
cargo install flamegraph\ncargo flamegraph --bin my_binary
\n\n

بعد التنفيذ، سيظهر ملف flamegraph.svg في جذر المشروع. افتحه في المتصفح - سترى فورًا أجزاء الكود "الساخنة".

\n\n

مثال عملي: تحسين محلل (Parser)

\n\n

لنفترض أننا نكتب محلل JSON بلغة Rust، وهو يعمل ببطء. سنستخدم تحليل الأداء لإيجاد المشكلة.

\n\n

الخطوة 1: قياس الأداء

\n\n

ننشئ اختبار أداء لتحليل ملف JSON كبير (مثلًا 10 ميجابايت). نشغل cargo bench ونرى أن التحليل يستغرق 2.5 ثانية. هذا كثير.

\n\n

الخطوة 2: Flamegraph

\n\n

نشغل cargo flamegraph على الملف الثنائي الذي يحلل هذا الملف. نفتح SVG ونرى أن 60% من الوقت

المدونات

توصيات الكتب