لماذا JMH
تجنب أخطاء قياس الأداء الساذجة
لماذا JMH درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
لماذا JMH
يُعدّ Java Microbenchmark Harness (JMH) الأداة القياسية لقياس أداء أجزاء صغيرة من شيفرة Java. وتنتج حلقات التوقيت المكتوبة يدويًا أرقامًا خاطئة في معظم الأحيان، لأن JVM بيئة تشغيل متطورة تُحسّن الشيفرة.
وُجد JMH للتغلب على هذه المشكلات.
الاختبار المعياري الساذج
تتمثّل المحاولة الأولى المعتادة في وضع حلقة داخل System.nanoTime(). يبدو هذا منطقيًا، لكنه يعاني عيوبًا جوهرية عند استخدامه لاختبارات الأداء الدقيق.
public class Main {
static int compute(int n) { return n * n + 7; }
public static void main(String[] args) {
long start = System.nanoTime();
int sink = 0;
for (int i = 0; i < 1_000_000; i++) sink = compute(i);
long elapsed = System.nanoTime() - start;
System.out.println("ns: " + elapsed + " sink=" + sink);
}
}المشكلة الأولى: إحماء JIT
تبدأ JVM في وضع التفسير، ولا تترجم الدوال كثيرة الاستخدام إلى شيفرة أصلية إلا بعد آلاف الاستدعاءات. لذلك يقيس الاختبار الساذج مرحلة التفسير البطيئة ممزوجة بمرحلة الترجمة السريعة، فتنتج متوسطات بلا معنى.
يحل JMH هذه المشكلة بمرحلة إحماء مخصّصة يتم تجاهل نتائجها.
المشكلة الثانية: إزالة الشيفرة الميتة
إذا لم تُستخدم نتيجة محسوبة قط، فقد يحذف JIT العملية الحسابية بالكامل. وعندها يقيس الاختبار حلقة فارغة.
يوفّر JMH استهلاك القيم المُعادة وBlackhole لمنع ذلك.
المشكلة الثالثة: طيّ الثوابت
إذا كانت المدخلات ثوابت معروفة وقت الترجمة، يحسب JIT النتيجة مرة واحدة ويعيد استخدامها. في المثال أدناه، يمكن للمترجم استبدال الحلقة بأكملها بثابت واحد.
يستخدم JMH كائنات @State لجعل المدخلات غير مكشوفة أمام المُحسِّن.
public class Main {
public static void main(String[] args) {
// 2 * 21 is constant; the JIT folds it to 42
int result = 2 * 21;
System.out.println(result);
}
}المشكلة الرابعة: تحسينات الحلقات
يفكّ JIT الحلقات، وينقل الشيفرة الثابتة خارجها، ويحوّل العمليات إلى عمليات متجهية. لذلك تقيس الحلقة المكتوبة يدويًا هذه التحسينات بدلًا من العملية التي قصدتم اختبارها.
يستبدل JMH حلقتكم بعدد تكرارات مضبوط بعناية ويتولى إدارته بنفسه.
المشكلة الخامسة: الاستبدال على المكدس
يمكن ترجمة حلقة طويلة تعمل داخل main أثناء التنفيذ (الاستبدال على المكدس)، فتنتج خصائص أداء تختلف عن خصائص دالة جرت ترجمتها بالطريقة المعتادة. ويؤدي ذلك إلى تحريف النتائج بصورة غير متوقعة.
ما الذي يوفّره JMH
- تكرارات إحماء منفصلة يتم تجاهل نتائجها.
- تكرارات قياس متعددة مع إحصاءات.
- التشغيل في JVMs جديدة لتجنّب تلوّث ملفات التعريف.
- استخدام Blackhole واستهلاك النتائج لمنع إزالة الشيفرة الميتة.
- كائنات @State لمنع طيّ الثوابت.
كيفية تشغيله
يُعدّ JMH اعتمادًا منفصلًا (org.openjdk.jmh)، ويُشغّل عادةً بواسطة معالج تعليقات توضيحية مع عملية بناء باستخدام Maven أو Gradle تُنتج ملف JAR قابلًا للتنفيذ. لا تشغّلوا الاختبارات المعيارية من main عادي كما تفعلون مع الشيفرة المعتادة.
الإحصاءات مهمة
لا يعرض JMH متوسطًا فحسب، بل يعرض أيضًا الخطأ / فاصل الثقة عبر التكرارات وعمليات التشغيل المنفصلة. تخبركم نتيجة مثل 42.0 +/- 1.3 ns/op بالقيمة المركزية وبمقدار التباين فيها، وهذا ضروري للوثوق بالقياس.
متى تلجؤون إلى JMH
استخدموا JMH عند مقارنة تطبيقين لمسار ساخن، أو التحقق من تحسين، أو قياس عمليات تستغرق من نانوثوانٍ إلى ميكروثوانٍ. أما الأعمال التي تستغرق ثوانٍ، مثل الإدخال والإخراج والشبكة، فعادةً ما يكفي لقياسها توقيت الساعة الفعلية.
تحقق سريع
تحقّقوا من فهمكم لسبب الحاجة إلى JMH.
مراجعة
تعلّمتم سبب حاجة اختبارات الأداء الدقيق إلى إطار اختبار:
- تُجري JVM إحماءً: تتحول الشيفرة المفسَّرة إلى شيفرة مترجمة بعد عدد كبير من الاستدعاءات.
- يمكن أن تؤدي إزالة الشيفرة الميتة وطيّ الثوابت إلى حذف العمل أو حسابه مسبقًا.
- تشوّه تحسينات الحلقات والاستبدال على المكدس نتائج الحلقات المكتوبة يدويًا.
- يضيف JMH الإحماء وتكرارات القياس والتشغيل المنفصل وBlackhole والإحصاءات.
- لجؤوا إليه عند قياس المسارات الساخنة التي تستغرق نانوثوانٍ.
الأسئلة الشائعة
هل درس «لماذا JMH» مجاني؟
نعم — نص درس «لماذا JMH» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «لماذا JMH»؟
تجنب أخطاء قياس الأداء الساذجة تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «لماذا JMH»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.