criterion في Rust: دليل شامل مع أمثلة عملية

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

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

ابدأ الدورة

مكتبة Criterion لـ Rust: اختبار الأداء الإحصائي

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

لماذا تحتاج هذه المكتبة؟ اختبار الأداء القياسي في Rust (عبر #[bench]) مفيد، لكنه يعاني من عيب أساسي: لا يأخذ في الاعتبار التشتت الإحصائي. المعالجات الحديثة لها بنية معقدة مع ذاكرة تخزين مؤقت (Cache)، ومتنبئات الفروع (Branch Predictors)، وتسريع التوربو (Turbo Boost). نفس الكود قد يُنفَّذ في أوقات مختلفة اعتمادًا على "ضوضاء" نظام التشغيل، أو حرارة المعالج، أو حالة الذاكرة المؤقتة العشوائية. Criterion يحل هذه المشكلة عن طريق تشغيل كل اختبار عدة مرات، وجمع عينة من أوقات التنفيذ، وتطبيق طرق إحصائية عليها (المتوسط، الوسيط، الانحراف المعياري، النسب المئوية). النتيجة ليست مجرد "وقت بالميكروثانية"، بل فاصل ثقة يقول: "باحتمال 95%، وقت التنفيذ الحقيقي يقع بين X و Y".

بالإضافة إلى ذلك، يوفر Criterion أدوات قوية لتحليل الانحدار (Regression Analysis). يمكنك مقارنة أداء نسختين من كودك (مثلًا قبل وبعد التحسين) والحصول على إجابة ذات دلالة إحصائية للسؤال: "هل النسخة الجديدة أسرع، أم أن الفرق ضمن هامش الخطأ؟". المكتبة تُنشئ تقارير HTML جميلة تحتوي على رسوم بيانية، ومخططات تكرارية، وجداول، مما يجعل تحليل الأداء واضحًا ومقنعًا. إنها أداة لا غنى عنها لمطوري المكتبات، ومحركات الألعاب، وقواعد البيانات، والخوارزميات التشفيرية، وأي كود آخر تكون فيه كل نانوثانية مهمة.

التثبيت

يتم تثبيت Criterion في مشروع Rust عبر مدير الحزم cargo. تحتاج إلى إضافة التبعية إلى ملف Cargo.toml لمشروعك. يُنصح بإضافتها كـ تبعية تطوير (dev-dependency)، لأن اختبارات الأداء ليست جزءًا من التطبيق النهائي.

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }

[[bench]]
name = "my_benchmark"
harness = false

الشرح:

  • version = "0.5" — يحدد إصدار المكتبة. وقت كتابة المقال، الإصدار الحالي هو 0.5.x.
  • features = ["html_reports"] — يُفعِّل إنشاء تقارير HTML مع رسوم بيانية. هذه ميزة اختيارية لكنها مفيدة جدًا.
  • [[bench]] — قسم يُخبر Cargo أن لدينا اختبار أداء باسم my_benchmark.
  • harness = false — يُعطِّل مشغل اختبارات الأداء المدمج في Cargo. هذا ضروري لكي يتمكن Criterion من السيطرة على العملية.

بعد ذلك، أنشئ ملفًا باسم benches/my_benchmark.rs (يجب أن يتطابق المسار مع الاسم المحدد في [[bench]]).

بداية سريعة: مثال عملي بسيط

لنكتب اختبار أداء بسيطًا يقيس سرعة حساب مجموع الأرقام من 1 إلى 1000.

// benches/my_benchmark.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn sum_up_to(n: u64) -> u64 {
    let mut sum = 0;
    for i in 1..=n {
        sum += i;
    }
    sum
}

fn bench_sum(c: &mut Criterion) {
    // black_box يمنع المحول البرمجي من تحسين الكود
    c.bench_function("sum 1000", |b| b.iter(|| sum_up_to(black_box(1000))));
}

criterion_group!(benches, bench_sum);
criterion_main!(benches);

كيفية التشغيل:

cargo bench

بعد التنفيذ، سترى في وحدة التحكم شيئًا مشابهًا لـ:

توصيات